生活随笔
收集整理的這篇文章主要介紹了
Java发送邮件链接实现登录注册
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
使用spring boot+OhMyEmail+Java-jwt實現整個過程
選用java-jwt的原因是因為項目需要和python后端算法配合,使用token進行通信,而python中的pyjwt庫對于簽名的處理與jjwt簽名的處理方式不一致,所以采用java-jwt實現Java端的jwt生成
通過圖片可以得知jjwt對于簽名轉成字節碼然后使用base64加密,這與官網jwt.io中對于前面的處理不一致。而java-jwt的簽名處理與jwt.io上的處理方式一致,從而使用pyjwt也可以通過相同密鑰進行解密。
對于郵件,采用的是OhMyEmail庫,這個庫是國人封裝javax-Email的,對于發送常用的郵件格式做了很好的封裝。
- 簡潔的郵件發送API
- 支持自定義發件人昵稱
- 支持擴展郵件Message
- 支持抄送/HTML/附件
- 支持異步發送
- 支持郵件模板
我主要使用他的支持郵件模板這個特點
對于整個過程的設計,參考了一下網上的方案,由于我采用的郵件注冊,通過郵件中的鏈接進行登錄。那么對于流程邏輯就涉及到了用戶選擇點擊或者不點擊鏈接登錄,或者用戶直接使用注冊時的賬號密碼嘗試登錄(即不點擊鏈接直接登陸,便失去了使用郵箱驗證的意義)。所以對于不點擊我們可以采取在用戶表增加字段來判斷用戶是否已經通過點擊鏈接登錄激活賬號。對于用戶點擊鏈接需要設置時效,這個可以token中的issedad以及expiredat字段屬性來進行設計,我設計的時效為一天。所以當用戶超過時效進行登錄是無效的,那么他再次嘗試注冊時,就可以通過檢查新增字段中的屬性來判斷是否已經注冊過但是尚未激活。簡而言之,失去時效即不可能登錄,登錄使用賬號密碼需要檢查是否激活,未激活就重新進行注冊。未失去時效進行點擊鏈接,則對新增字段屬性進行重置激活。
記錄出現的問題:
問題1:前端設置"ContentType/json;charst=utf-8"
由于后端我們使用的RequestBody,前端需要傳輸json字符串,所以需要設置頭。同時處理前端數據,使用JSON.Stringfy()將對象轉化為Json字符串。避免出現類型不匹配以及后端報錯contenttype無法處理
問題2:發送郵件時使用 Pebble庫渲染html文件
這個渲染html文件,我在python做后端的時候用到過,比如flask以及fastapi都是通過template來進行前端樣式渲染。但是在java中還是第一次使用。渲染時,注意需要生成的html文件不要增加html的頭那些格式,只要html的body部分,不然會被處理為垃圾郵件自動攔截
其次就是對于html文件放置在src/java/resource下但是未被查找到,可能設置了文件過濾,在pom文件中對.html后綴文件進行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("這是一封來自某不知名禿頭大哥登錄驗證的郵件").from("其實頭發很多哈哈哈").to(user
.getEmail()).html(output
).send();} catch (IOException e
) {throw new DefinationException(20001,"發送郵件失敗");}return R
.ok();}
<div
><p
>親愛的
<b
>{{ username
}}</b
>, 歡迎加入 IIM
!</p
><p
>當您收到這封信的時候,您已經可以正常登錄了。
</p
><p
>請點擊鏈接登錄首頁
: <a href
="{{ loginUrl }}"> {{ loginUrl
}}</a
></p
><p
>如果您的 email 程序不支持鏈接點擊,請將上面的地址拷貝至您的瀏覽器
(如IE
)的地址欄進入。
</p
><p
>如果您還想申請管理員權限,可以聯系管理員
{{ adminEmail
}}</p
><p
>我們對您產生的不便,深表歉意。
</p
><p
>希望您在 IIM時序數據異常檢測 系統度過快樂的時光
!</p
><p
></p
><p
>-----------------------</p
><p
></p
><p
>(這是一封自動產生的email,請勿回復。
)</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("創建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 我個人覺得沒什么必要了解,但是可以看看
總結
以上是生活随笔為你收集整理的Java发送邮件链接实现登录注册的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。