user_session_management.png
服務(wù)器端需要對客戶端發(fā)起訪問的進(jìn)行合法性校驗(yàn):
- 證明你是你
- 鑒權(quán)(本文不涉及此內(nèi)容)
分配 UserAccessToken 流程
+----------+ +-----------------+
| auth +---->+ accessToken |
+----------+ +-----------------+
用戶鑒權(quán)之后 Server 為用戶分配一個(gè)訪問令牌,后續(xù)所有請求 Header中 均攜帶此令牌供服務(wù)器校驗(yàn)拟烫。
校驗(yàn)
服務(wù)器來承認(rèn)這個(gè)令牌(AccessToken)由它頒發(fā)的并且有效虑瀑。
- 令牌生成時(shí)服務(wù)器存儲(chǔ) userId/accessToken/exprieIn
- 令牌校驗(yàn)時(shí)服務(wù)器查詢存儲(chǔ)中是否包含此記錄且沒過期
存儲(chǔ)
服務(wù)器內(nèi)存(分布式內(nèi)存框架)/傳統(tǒng)RDMS/NoSQL(Redis/Memcached)
DynamoDB
- 存儲(chǔ)大
- 延遲低
- 擴(kuò)展快
DynamoDBUserAccessToken.java
@DynamoDBTable(tableName = "user_access_token")
public class DynamoDBUserAccessToken {
private Long uid;
private String accessToken;
private Long expiresIn;
private String refreshToken;
private Date refreshTime = new Date();
private Date createTime = new Date();
public DynamoDBUserAccessToken() {
}
public DynamoDBUserAccessToken(Long uid) {
super();
this.uid = uid;
}
@DynamoDBHashKey(attributeName = "uid")
public Long getUid() {
return uid;
}
@DynamoDBAttribute(attributeName = "access_token")
public String getAccessToken() {
return accessToken;
}
@DynamoDBAttribute(attributeName = "expires_in")
public Long getExpiresIn() {
return expiresIn;
}
@DynamoDBAttribute(attributeName = "refresh_token")
public String getRefreshToken() {
return refreshToken;
}
@DynamoDBAttribute(attributeName = "refresh_time")
public Date getRefreshTime() {
return refreshTime;
}
@DynamoDBAttribute(attributeName = "create_time")
public Date getCreateTime() {
return createTime;
}
// .. 省略 setter 方法
}
DynamoDBConfig.java
@Configuration
public class DynamoDBConfig {
@Bean
AmazonDynamoDB amazonDynamoDB() {
return AmazonDynamoDBClientBuilder
.standard()
.withRegion(Regions.US_WEST_2)
.withCredentials(new PropertiesFileCredentialsProvider("/data/aws-credentials/clipchat-dev.properties"))
.build();
}
@Bean
DynamoDBMapper dynamoDBMapper() {
return new DynamoDBMapper(amazonDynamoDB(), new TableNameOverride("user_access_token").config());
}
@Bean
AccessTokenConverter accessTokenConverter() {
return new AccessTokenConverter(new DefaultDynamoDBUserAccessTokenConverter(),
new DefaultUserAccessTokenConverter());
}
}
UserAccessTokenRepository.java
@Repository
public class UserAccessTokenRepository {
@Autowired
private DynamoDBMapper dynamoDBMapper;
@Autowired
private AccessTokenConverter accessTokenConverter;
public UserAccessToken getUserAccessToken(Long uid) {
DynamoDBUserAccessToken dynamoDBUserAccessToken = dynamoDBMapper.load(new DynamoDBUserAccessToken(uid));
if (null != dynamoDBUserAccessToken) {
accessTokenConverter.toUserAccessToken(dynamoDBUserAccessToken);
}
return null;
}
public void deleteUserAccessToken(Long uid) {
dynamoDBMapper.delete(new DynamoDBUserAccessToken(uid));
}
public void saveUserAccessToken(UserAccessToken userAccessToken) {
dynamoDBMapper.save(accessTokenConverter.toDynamoUserAccessToken(userAccessToken));
}
}
至此,關(guān)鍵代碼部分已羅列完畢