java 实现token登录,并进行上下文存储用户信息 您所在的位置:网站首页 java模拟浏览器登陆获取token java 实现token登录,并进行上下文存储用户信息

java 实现token登录,并进行上下文存储用户信息

2024-06-29 06:41| 来源: 网络整理| 查看: 265

在Java中实现token登录上下文存储用户信息,可以使用Java Web框架(如Spring Boot)和JWT(JSON Web Token)来实现。

首先,需要引入相关依赖。在pom.xml文件中添加以下依赖:

org.springframework.boot spring-boot-starter-security io.jsonwebtoken jwt-api 0.11.2 io.jsonwebtoken jwt-impl 0.11.2 runtime io.jsonwebtoken jwt-jackson 0.11.2 runtime 接下来,创建一个类来处理token的生成和验证逻辑。例如,创建一个名为TokenUtil的类: import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.stereotype.Component; import java.util.Date; @Component public class TokenUtil { private static final String SECRET_KEY = "your_secret_key"; // 设置密钥 public String generateToken(String username) { Date now = new Date(); Date expiryDate = new Date(now.getTime() + 3600000); // 设置token过期时间为1小时 return Jwts.builder() .setSubject(username) .setIssuedAt(now) .setExpiration(expiryDate) .signWith(SignatureAlgorithm.HS512, SECRET_KEY) .compact(); } public String getUsernameFromToken(String token) { Claims claims = Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(token) .getBody(); return claims.getSubject(); } public boolean validateToken(String token) { try { Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token); return true; } catch (Exception e) { return false; } } } 接下来,在用户登录成功后,可以生成一个token并将其返回给客户端。例如,创建一个名为LoginController的类: import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController public class LoginController { @Autowired private TokenUtil tokenUtil; @PostMapping("/login") public String login(@RequestBody User user) { // 验证用户名和密码 if (user.getUsername().equals("admin") && user.getPassword().equals("password")) { // 登录成功,生成token String token = tokenUtil.generateToken(user.getUsername()); // 如果用户信息量比较多,可以将用户信息存入非关系型数据库 //String userName = request.getHeader("username"); //String passWord = request.getHeader("password"); //UserInfoEntity user = new UserInfoEntity(); //user.setUsername(userName); //redisTemplate.opsForValue().set(token , user); return token; } else { // 登录失败 return "Invalid username or password"; } } } 1.在其他需要验证用户身份的请求中,可以使用拦截器或过滤器或AOP来验证token,并从token中获取用户信息。例如,创建一个名为AuthInterceptor的拦截器 import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Component public class AuthInterceptor implements HandlerInterceptor { @Autowired private TokenUtil tokenUtil; @Resource private WebContext webContext; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 从请求头中获取token String token = request.getHeader("Authorization"); if (token != null && token.startsWith("Bearer ")) { token = token.substring(7); // 去掉"Bearer "前缀 // 验证token是否有效 if (tokenUtil.validateToken(token)) { String username = tokenUtil.getUsernameFromToken(token); // 将用户信息存储在上下文中,供后续使用 webContext.setCurrentUser(username); return true; } } response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 返回401未授权状态码 return false; } } import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import sun.misc.Request; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.util.Collection; @Component public class WebContext { private static final String USER_ATTRIBUTES = "USER_ATTRIBUTES"; @Resource private RedisUtil redisUtil; /** * Sets current user. * * @param user the user */ public void setCurrentUser(UserInfoEntity user) { RequestContextHolder.currentRequestAttributes().setAttribute(USER_ATTRIBUTES, user, RequestAttributes.SCOPE_REQUEST); } /** * Gets current user. * * @return the current user */ public UserInfoEntity getCurrentUser() { UserInfoEntity user = (UserInfoEntity) RequestContextHolder.currentRequestAttributes().getAttribute(USER_ATTRIBUTES, RequestAttributes.SCOPE_REQUEST); try { if (null != user) { return user; } else { ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); HttpServletRequest request = requestAttributes.getRequest(); String token = request.getHeader("token"); user = (UserInfoEntity) redisUtil.get(token); if (null == user) { throw new LoginException(LoginExceptionEnum.NOT_LOGIN_ERROR.getCode(), LoginExceptionEnum.NOT_LOGIN_ERROR.getDesc()); } setCurrentUser(user); return user; } } catch (LoginException e) { e.printStackTrace(); throw new RuntimeException(""); } } } 采用aop的形式 import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.util.Objects; @Slf4j @Aspect @Component public class LoginAspect { @Resource private RedisUtil redisUtil; @Resource private WebContext webContext; @Resource RedisTemplate redisTemplate; @Pointcut("execution(public * com.tairui.energy.controller.*.*(..)) " + "&& !execution(public * com.tairui.energy.controller.LoginController.login(..))) ") public void loginCheck() { } @Before("loginCheck()") public void checkParam(JoinPoint pjp) throws Throwable { // 接收到请求,记录请求内容 try { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); String token = request.getHeader(BaseConstant.TOKEN); if(token==null){ throw new LoginException(LoginExceptionEnum.NOT_LOGIN_ERROR.getCode(), LoginExceptionEnum.NOT_LOGIN_ERROR.getDesc()); } UserInfoEntity obj = (UserInfoEntity)redisUtil.get(token); if (null == webContext.getCurrentUser()) { webContext.setCurrentUser(obj); } if (Objects.isNull(obj)) { log.error("************该用户TOKEN已过期!*************"); throw new LoginException(LoginExceptionEnum.NOT_LOGIN_ERROR.getCode(), LoginExceptionEnum.NOT_LOGIN_ERROR.getDesc()); } boolean set = redisUtil.expire(token, 1000 * 3600 * 4); } catch (LoginException e) { e.printStackTrace(); throw new LoginException(LoginExceptionEnum.NOT_LOGIN_ERROR.getCode(), e.getLocalizedMessage()); } } }

####最后,在需要获取用户信息的地方,可以通过UserContext类来获取当前登录用户的信息。

public class TestService { @Resource private WebContext webContext; public void doSomething() { String username = webContext.getUser(); // 使用username进行相应的操作... } }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有