Google Authenticator實作
今天要跟大家介紹一個2階段驗證的解決方案 Google Authenticator
。
在開始之前,我們可能要先跟大家介紹兩個專有名詞,分別是 OTP
與 TOTP
。
OTP
是什麼呢?事實上在我們的生活中最常見的使用場景就是『信用卡交易』,我們在進行信用卡交易時會收到一個簡訊驗證碼,並在交易的過程中輸入此驗證碼並進行驗證,雖然使我們的交易更安全但還是有幾個缺點,如電話號碼更新的不方便、所在的地方無法收到簡訊、交易成本提高…等因素。
也因如此有了以『時間』為基礎的 OTP
驗證方式,這方式是,client 與 server 以目前當前時間加上密鑰透過演算法所產生出來的 6 位數字。
公式如下:
TOTP
=func
(時間
+密鑰
)
Quick Start
Google Authenticator
可在你的手機上產生兩步驟驗證碼。若想進一步瞭解兩步驟驗證:https://g.co/2step
我們這次預期要有兩個 Controller
- 取得 Google Authenticator QrCode
- 驗證 Auth Code是否正確
Source Code
在 User 表中,加入 googleAuthSecretKey
的屬性,若 googleAuthSecretKey
為 null 則產生一組 secretKey。
然後 call GoogleAuthenticatorUtil.createGoogleAuthQRCodeData
取得 QRCode。1
2
3
4
5
6
7
8
9
10
11
12@ApiOperation(value = "取得Google Auth QRCode資訊")
@GetMapping("/googleAuthQRCode")
@Secured({"ROLE_ADMIN", "ROLE_USER"})
public ResponseEntity getGoogleAuthQRCode(@ApiIgnore @CurrentUser UserPrincipal currentUser) {
User user = userService.getUserById(currentUser.getId());
if(StringUtils.isBlank(user.getGoogleAuthSecretKey())) {
user.setGoogleAuthSecretKey(GoogleAuthenticatorUtil.createSecretKey());
userService.updateByPrimaryKey(user);
}
String authQRCode = GoogleAuthenticatorUtil.createGoogleAuthQRCodeData(user.getGoogleAuthSecretKey(), user.getName(), ISSUER);
return ResponseEntity.ok(authQRCode);
}
取得 User 表中的 googleAuthSecretKey
進行 GoogleAuthenticatorUtil.verify
驗證1
2
3
4
5
6
7
8
9
10
11
12@ApiOperation(value = "驗證Google Auth")
@GetMapping("/googleAuthQRCode/{verifyCode}")
@Secured({"ROLE_ADMIN", "ROLE_USER"})
public ResponseEntity checkGoogleAuthQRCode(@ApiIgnore @CurrentUser UserPrincipal currentUser,
@PathVariable String verifyCode) {
boolean checkGoogleAuthQRCode = false;
User user = userService.getUserById(currentUser.getId());
if(StringUtils.isNotBlank(user.getGoogleAuthSecretKey())) {
checkGoogleAuthQRCode = GoogleAuthenticatorUtil.verify(user.getGoogleAuthSecretKey(), verifyCode);
}
return ResponseEntity.ok(checkGoogleAuthQRCode);
}
驗證
Swagger - {URI/googleAuthQRCode}
使用 QRCode Generator
Reference
Google Authenticator
TOTP: Time-Based One-Time Password Algorithm
Donate
謝謝您的支持與鼓勵