生活随笔
收集整理的這篇文章主要介紹了
Java发送邮件链接实现登录注册
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
使用spring boot+OhMyEmail+Java-jwt實(shí)現(xiàn)整個(gè)過程
選用java-jwt的原因是因?yàn)轫?xiàng)目需要和python后端算法配合,使用token進(jìn)行通信,而python中的pyjwt庫對于簽名的處理與jjwt簽名的處理方式不一致,所以采用java-jwt實(shí)現(xiàn)Java端的jwt生成
通過圖片可以得知jjwt對于簽名轉(zhuǎn)成字節(jié)碼然后使用base64加密,這與官網(wǎng)jwt.io中對于前面的處理不一致。而java-jwt的簽名處理與jwt.io上的處理方式一致,從而使用pyjwt也可以通過相同密鑰進(jìn)行解密。
對于郵件,采用的是OhMyEmail庫,這個(gè)庫是國人封裝javax-Email的,對于發(fā)送常用的郵件格式做了很好的封裝。
- 簡潔的郵件發(fā)送API
- 支持自定義發(fā)件人昵稱
- 支持?jǐn)U展郵件Message
- 支持抄送/HTML/附件
- 支持異步發(fā)送
- 支持郵件模板
我主要使用他的支持郵件模板這個(gè)特點(diǎn)
對于整個(gè)過程的設(shè)計(jì),參考了一下網(wǎng)上的方案,由于我采用的郵件注冊,通過郵件中的鏈接進(jìn)行登錄。那么對于流程邏輯就涉及到了用戶選擇點(diǎn)擊或者不點(diǎn)擊鏈接登錄,或者用戶直接使用注冊時(shí)的賬號密碼嘗試登錄(即不點(diǎn)擊鏈接直接登陸,便失去了使用郵箱驗(yàn)證的意義)。所以對于不點(diǎn)擊我們可以采取在用戶表增加字段來判斷用戶是否已經(jīng)通過點(diǎn)擊鏈接登錄激活賬號。對于用戶點(diǎn)擊鏈接需要設(shè)置時(shí)效,這個(gè)可以token中的issedad以及expiredat字段屬性來進(jìn)行設(shè)計(jì),我設(shè)計(jì)的時(shí)效為一天。所以當(dāng)用戶超過時(shí)效進(jìn)行登錄是無效的,那么他再次嘗試注冊時(shí),就可以通過檢查新增字段中的屬性來判斷是否已經(jīng)注冊過但是尚未激活。簡而言之,失去時(shí)效即不可能登錄,登錄使用賬號密碼需要檢查是否激活,未激活就重新進(jìn)行注冊。未失去時(shí)效進(jìn)行點(diǎn)擊鏈接,則對新增字段屬性進(jìn)行重置激活。
記錄出現(xiàn)的問題:
問題1:前端設(shè)置"ContentType/json;charst=utf-8"
由于后端我們使用的RequestBody,前端需要傳輸json字符串,所以需要設(shè)置頭。同時(shí)處理前端數(shù)據(jù),使用JSON.Stringfy()將對象轉(zhuǎn)化為Json字符串。避免出現(xiàn)類型不匹配以及后端報(bào)錯(cuò)contenttype無法處理
問題2:發(fā)送郵件時(shí)使用 Pebble庫渲染html文件
這個(gè)渲染html文件,我在python做后端的時(shí)候用到過,比如flask以及fastapi都是通過template來進(jìn)行前端樣式渲染。但是在java中還是第一次使用。渲染時(shí),注意需要生成的html文件不要增加html的頭那些格式,只要html的body部分,不然會被處理為垃圾郵件自動攔截
其次就是對于html文件放置在src/java/resource下但是未被查找到,可能設(shè)置了文件過濾,在pom文件中對.html后綴文件進(jìn)行include即可被編譯到target中去
public class EmailUtil {public static final String username
="xxxx@qq.com";public static final String password
="xxxxxxxx";public static void initOhMyEmail(){OhMyEmail
.config(OhMyEmail
.SMTP_QQ(false),username
,password
);}
}
@
PostMapping("registerByEmail")public R
loginByEmail(@RequestBody User user
) throws SendMailException
{user
.setState(0);String id
=userService
.register(user
);String token
=JwtAuth
.getJavaToken(id
, user
.getEmail(),user
.getPhoneNumber());String loginUrl
=constValue
.INDEXURL
+"?token="+token
;EmailUtil
.initOhMyEmail();PebbleEngine engine
= new PebbleEngine
.Builder().build();PebbleTemplate compiledTemplate
= engine
.getTemplate("register.html");Map
<String
, Object
> context
= new HashMap<String, Object>();context
.put("username", user
.getEmail());context
.put("loginUrl",loginUrl
);context
.put("adminEmail", constValue
.ADMINEMAIL
);try {Writer writer
= new StringWriter();compiledTemplate
.evaluate(writer
, context
);String output
= writer
.toString();OhMyEmail
.subject("這是一封來自某不知名禿頭大哥登錄驗(yàn)證的郵件").from("其實(shí)頭發(fā)很多哈哈哈").to(user
.getEmail()).html(output
).send();} catch (IOException e
) {throw new DefinationException(20001,"發(fā)送郵件失敗");}return R
.ok();}
<div
><p
>親愛的
<b
>{{ username
}}</b
>, 歡迎加入 IIM
!</p
><p
>當(dāng)您收到這封信的時(shí)候,您已經(jīng)可以正常登錄了。
</p
><p
>請點(diǎn)擊鏈接登錄首頁
: <a href
="{{ loginUrl }}"> {{ loginUrl
}}</a
></p
><p
>如果您的 email 程序不支持鏈接點(diǎn)擊,請將上面的地址拷貝至您的瀏覽器
(如IE
)的地址欄進(jìn)入。
</p
><p
>如果您還想申請管理員權(quán)限,可以聯(lián)系管理員
{{ adminEmail
}}</p
><p
>我們對您產(chǎn)生的不便,深表歉意。
</p
><p
>希望您在 IIM時(shí)序數(shù)據(jù)異常檢測 系統(tǒng)度過快樂的時(shí)光
!</p
><p
></p
><p
>-----------------------</p
><p
></p
><p
>(這是一封自動產(chǎn)生的email,請勿回復(fù)。
)</p
>
</div
>
public static final long EXPIRE
= 1000 * 60 * 60 * 24; public static final String APP_SECRET
= "xclxzlxzlxzlxzlxzlxz"; public static String
getJavaToken(String id
,String email
,String phoneNumber
){String token
="";Map
<String
, Object
> headerClaims
= new HashMap<>();headerClaims
.put("alg","HS256");headerClaims
.put("typ","JWT");try{token
= JWT
.create().withHeader(headerClaims
).withIssuedAt(new Date()).withExpiresAt(new Date(System
.currentTimeMillis()+EXPIRE
)).withClaim("id",id
).withClaim("phoneNumber",phoneNumber
).withClaim("email",email
).sign(Algorithm
.HMAC256(APP_SECRET
));}catch(JWTCreationException
| UnsupportedEncodingException e
){System
.out
.println("創(chuàng)建java-jwt失敗");}return token
;}
public static String
getMemberIdByJwtToken(HttpServletRequest request
){String jwtToken
= request
.getHeader("token");if(StringUtils
.isEmpty(jwtToken
)) return "";JWTVerifier verifier
=null
;try{verifier
= JWT
.require(Algorithm
.HMAC256(APP_SECRET
)).build();} catch (UnsupportedEncodingException e
) {e
.printStackTrace();}DecodedJWT jwt
=null
;try{jwt
=verifier
.verify(jwtToken
);}catch (SignatureVerificationException e
){throw new DefinationException(20001,"token失效,重新登錄");}return jwt
.getClaim("id").asString();}
貼出java-jwt 的builder下的方法,主要看看with開頭的方法即可
對于acceptleeway 我個(gè)人覺得沒什么必要了解,但是可以看看
總結(jié)
以上是生活随笔為你收集整理的Java发送邮件链接实现登录注册的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。