服务器端需要对客户端发起访问的进行合法性校验:
- 证明你是你
- 鉴权(本文不涉及此内容)
分配 UserAccessToken 流程
+----------+ +-----------------+
| auth +---->+ accessToken |
+----------+ +-----------------+
用户鉴权之后 Server 为用户分配一个访问令牌,后续所有请求 Header中 均携带此令牌供服务器校验。
校验
服务器来承认这个令牌(AccessToken)由它颁发的并且有效。
- 令牌生成时服务器存储 userId/accessToken/exprieIn
- 令牌校验时服务器查询存储中是否包含此记录且没过期
存储
服务器内存(分布式内存框架)/传统RDMS/NoSQL(Redis/Memcached)
DynamoDB
- 存储大
- 延迟低
- 扩展快
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));
}
}
至此,关键代码部分已罗列完毕