版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shenzhen_zsw/article/details/89456755
目录
用户服务—基于JWT的Token认证实现登录、鉴权接口
基于session身份认证方案
基于token身份认证方案
JWT介绍
pom.xml
......
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.1.0</version>
</dependency>
......
JwtHelper
package com.mooc.house.user.utils;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Map;
import org.apache.commons.lang3.time.DateUtils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.google.common.collect.Maps;
public class JwtHelper {
private static final String SECRET = "session_secret";
private static final String ISSUER = "mooc_user";
/**
* 生成token
* @param claims
* @return
*/
public static String genToken(Map<String, String> claims){
try {
Algorithm algorithm = Algorithm.HMAC256(SECRET);
JWTCreator.Builder builder = JWT.create().withIssuer(ISSUER).withExpiresAt(DateUtils.addDays(new Date(), 1));
claims.forEach((k,v) -> builder.withClaim(k, v));
return builder.sign(algorithm).toString();
} catch (IllegalArgumentException | UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
/**
* 根据token获取对应的信息
* 验证token
* @param token
* @return
*/
public static Map<String, String> verifyToken(String token) {
Algorithm algorithm = null;
try {
algorithm = Algorithm.HMAC256(SECRET);
} catch (IllegalArgumentException | UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
JWTVerifier verifier = JWT.require(algorithm).withIssuer(ISSUER).build();
DecodedJWT jwt = verifier.verify(token);
Map<String, Claim> map = jwt.getClaims();
Map<String, String> resultMap = Maps.newHashMap();
map.forEach((k,v) -> resultMap.put(k, v.asString()));
return resultMap;
}
}
说明:
1)生成token;
2)验证token;
登录、鉴权
1)用户控制器,鉴权;
@RequestMapping("auth")
public RestResponse<User> auth(@RequestBody User user){
User finalUser = userService.auth(user.getEmail(),user.getPasswd());
return RestResponse.success(finalUser);
}
2)用户service
/**
* 校验用户名密码、生成token并返回用户对象
* @param email
* @param passwd
* @return
*/
public User auth(String email, String passwd) {
if (StringUtils.isBlank(email) || StringUtils.isBlank(passwd)) {
throw new UserException(Type.USER_AUTH_FAIL,"User Auth Fail");
}
User user = new User();
user.setEmail(email);
user.setPasswd(HashUtils.encryPassword(passwd));
user.setEnable(1);
List<User> list = getUserByQuery(user);
if (!list.isEmpty()) {
User retUser = list.get(0);
onLogin(retUser);
return retUser;
}
throw new UserException(Type.USER_AUTH_FAIL,"User Auth Fail");
}
public List<User> getUserByQuery(User user) {
List<User> users = userMapper.select(user);
users.forEach(u -> {
u.setAvatar(imgPrefix + u.getAvatar());
});
return users;
}
/**
* 登录
* @param user
*/
private void onLogin(User user) {
//根据登录用户信息生成token
String token = JwtHelper.genToken(
ImmutableMap.of(
"email", user.getEmail(),
"name", user.getName(),
"ts", Instant.now().getEpochSecond()+""
)
);
// 更新令牌(缓存中的数据)
renewToken(token,user.getEmail());
user.setToken(token);
}
private String renewToken(String token, String email) {
redisTemplate.opsForValue().set(email, token);
redisTemplate.expire(email, 30, TimeUnit.MINUTES);
return token;
}
说明:
1)校验用户名密码、生成token并返回鉴权信息;
2)并在reids中设置用户令牌信息和过期日期;
获取用户信息
1)用户控制器
提供根据用户token获取用户信息
@RequestMapping("get")
public RestResponse<User> getUser(String token){
User finalUser = userService.getLoginedUserByToken(token);
return RestResponse.success(finalUser);
}
2)用户服务
public User getLoginedUserByToken(String token) {
Map<String, String> map = null;
try {
map = JwtHelper.verifyToken(token);
} catch (Exception e) {
throw new UserException(Type.USER_NOT_LOGIN,"User not login");
}
String email = map.get("email");
Long expired = redisTemplate.getExpire(email);
if (expired > 0L) {
renewToken(token, email);
User user = getUserByEmail(email);
user.setToken(token);
return user;
}
throw new UserException(Type.USER_NOT_LOGIN,"user not login");
}
说明:
1)根据token,获取token认证信息;
2)从token认证信息中获取登录用户邮箱;
3)从redis中判断当前用户是否过期;
4)没有过期,则重新设置过期时间;
==============================
QQ群:143522604
群里有相关资源
欢迎和大家一起学习、交流、提升!
==============================