两种常规的登录方法(session+redis,jwt)

最近做个小项目要实现登录后验证用户是否已经登录,如果是就运行该接口执行,否则不能操作

一,常规方法session加redis

客服端传入用户名和密码,如果用户名和密码都正确,就根据session的id在redis生成一个唯一的键,值就是该用户的信息

代码:

@Autowired
	UserService userService;
	@Autowired
	RedisUtil redisUtil;
	@PostMapping("login")
	public Object login(@RequestBody User user, HttpServletRequest request){
		String id = request.getSession().getId();
		User one = userService.getOne(new QueryWrapper<>(new User()).eq("username", user.getUsername()));
		if(one==null){
			throw new RuntimeException("没有该用户");
		}else{
			if(one.getPassword().equals(user.getPassword())){
				redisUtil.set("User_"+id, one);
				return one;
			}else{
				throw new RuntimeException("密码错误");
			}
		}
	}
	@GetMapping("users")
	public String users(HttpServletRequest request){
		Object token = (Object)request.getParameter("token");
		if(redisUtil.get(token)!=null){
			return "已经登录了,可以操作";
		}else{
			return "还没有登录";
		}
	}

代码运行结果
在这里插入图片描述

redis里面的sessionid在这里插入图片描述
在这里插入图片描述
如果token不对
在这里插入图片描述

二、jwt方法

jwt工具类

@Configuration
/*@ConfigurationProperties(prefix = "jwt.token")*/
public class JwtTokenUtil {
	public static void setSecret(String secret) {
		JwtTokenUtil.secret = secret;
	}

	public static void setExpiration(int expiration) {
		JwtTokenUtil.expiration = expiration;
	}

	private static String secret="winner";
	private static long expiration=1000*60*60*24;
	private static final String CLAIM_KEY_USERNAME="sub";
	private static final String CLAIM_KEY_ID="id";
	private static final String CLAIM_KEY_CREATED="created";
	private static final String CLAIM_KEY_ROLES="roles";

	//获得的token中得到用户
	public static String getUsernameFromToken(String token){
		String username;
		try {
			username=getClaimsFromToken(token).getSubject();
		}catch (Exception e){
			username=null;
		}
		return username;
	}

	//获得token中的时间
	public static Date getCreatedDateFromToken(String token){
		Date date;
		try {
			final Claims claims=getClaimsFromToken(token);
			date=new Date((Long)claims.get(CLAIM_KEY_CREATED));
		}catch (Exception e)
		{
			date=null;
		}
		return date;
	}

	//从token中获得过期时间
	public static Date getExpirationDateFromToken(String token) {
		Date expiration;
		try {
			final Claims claims = getClaimsFromToken(token);
			expiration = claims.getExpiration();
		} catch (Exception e) {
			expiration = null;
		}
		return expiration;
	}
	//解析token
	private static Claims getClaimsFromToken(String token) {
		Claims claims;
		try {
			System.out.println(1);
			claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
		} catch (ExpiredJwtException e) {
			System.out.println(2);
			claims=e.getClaims();
		}
		return claims;


	}

	//生成过期时间
	private static Date generateExpirationDate(){
		//过期事件
		return new Date(System.currentTimeMillis()+ expiration);
	}
	//userDetails中的信息加入到token并调用generateToken生产token
	public static String generateToken(User userDetails){
		Map<String,Object> claims=new HashMap<>();
		claims.put(CLAIM_KEY_USERNAME,userDetails.getUsername());
		claims.put(CLAIM_KEY_CREATED,new Date());
		claims.put(CLAIM_KEY_ID,userDetails.getId());
		return generateToken(claims);
	}

	//生产token
	public static String generateToken(Map<String,Object> claims){
		return Jwts.builder()
				.setClaims(claims)
				.setExpiration(generateExpirationDate())
				.signWith(SignatureAlgorithm.HS512,secret)
				.compact();
	}

	//判断是否在是否在过期时间之前
	private static Boolean isTokenExpired(String token){
		final Date expiration=getExpirationDateFromToken(token);
		return expiration.before(new Date());
	}

	//判断是否可以刷下
	public static Boolean canTokenBeRefreshed(String token){
		return !isTokenExpired(token);
	}

	//刷新token把CLAIM_KEY_CREATED刷新了
	public static String refreshToken(String token){
		String refreshedToken;
		try{
			final Claims claims=getClaimsFromToken(token);
			claims.put(CLAIM_KEY_CREATED,new Date());
			refreshedToken=generateToken(claims);
		}catch(Exception e){
			refreshedToken=null;
		}
		return refreshedToken;
	}

	//判断token是否过期,是否可用
	public static Boolean validateToken(String token){
		final String username=getUsernameFromToken(token);
		final Date created=getCreatedDateFromToken(token);
		return username.equals(isTokenExpired(token));
	}
	/**
	 * 判断token是否存在与有效
	 * @param jwtToken
	 * @return
	 */
	public static boolean checkToken(String jwtToken) {
		if (StringUtils.isEmpty(jwtToken)) return false;
		try {
			Jwts.parser().setSigningKey(secret).parseClaimsJws(jwtToken);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
	/**
	 * 根据token获取会员名字
	 * @return
	 */
	public static String getUsernameByJwtToken(String token) {
		if(StringUtils.isEmpty(token)) return "";
		Jws<Claims> claimsJws =
				Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
		Claims claims = claimsJws.getBody();
		return (String)claims.get(CLAIM_KEY_USERNAME);
	}
}

控制层

@PostMapping("jwtLogin")
	public Object jwtLogin(@RequestBody User user){
		User one = userService.getOne(new QueryWrapper<>(new User()).eq("username", user.getUsername()));
		if(one==null){
			throw new RuntimeException("没有该用户");
		}else{
			if(one.getPassword().equals(user.getPassword())){
				//生成token
				String s = JwtTokenUtil.generateToken(one);
				return "登录成功:生成的token是"+s;
			}else{
				throw new RuntimeException("密码错误");
			}
		}
	}
	@GetMapping("jwtUsers")
	public String jwtUsers(HttpServletRequest request){
		String token = request.getParameter("token");
		SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:MM:ss");
		Date createdDateFromToken = JwtTokenUtil.getCreatedDateFromToken(token);
		Date date = JwtTokenUtil.getExpirationDateFromToken(token);
		/*simpleDateFormat.format(createdDateFromToken);
		simpleDateFormat.format(date);*/
		System.out.println("查看过期时间"+simpleDateFormat.format(date)+"生成日期"+simpleDateFormat.format(createdDateFromToken));
		if(JwtTokenUtil.checkToken(token)){
			String username = JwtTokenUtil.getUsernameByJwtToken(token);
			return "已经登录了,可以操作,根据token生成名字"+username;
		}else{
			return "还没有登录";
		}
	}

运行结果

在这里插入图片描述

在这里插入图片描述
两个都是简单实现,很多细致的功能还没有实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值