当前位置: 首页>后端>正文

JWT案例二

JWT案例二,第1张

JWT 请求流程

用户使用账号和密码发起POST 请求;

服务器使用私钥创建一个JWT;

服务器返回这个JWT 给浏览器;

浏览器将该JWT 串在请求头中像服务器发送请求;

服务器验证该JWT;

返回响应的资源给浏览器。

<!-- 引入jwt-->

<dependency>

<groupId>com.auth0</groupId>

<artifactId>java-jwt</artifactId>

<version>3.8.2</version>

</dependency>

<dependency>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

<optional>true</optional>

</dependency>

用户类

@Data

@AllArgsConstructor

@NoArgsConstructor

public class User {

????private Integer id;

????private String userName;

????private String password;

}

Jwt工具类

/**

* Jwt工具类进行token的生成和认证

*/

public class JwtUtil {

private static final Logger logger = LoggerFactory.getLogger(JwtUtil.class);

/**

* 密钥

*/

private static final String SECRET = "my_secret";

/**

* 过期时间

**/

private static final long EXPIRATION = 1800L;//单位为秒

/**

* 生成用户token,设置token超时时间

*/

public static String createToken(User user) {

//过期时间

Date expireDate = new Date(System.currentTimeMillis() + EXPIRATION * 1000);

Map<String, Object> map = new HashMap<>();

map.put("alg", "HS256");

map.put("typ", "JWT");

String token = JWT.create()

.withHeader(map)// 添加头部

//可以将基本信息放到claims中

.withClaim("id", user.getId())//userId

.withClaim("userName", user.getUserName())//userName

.withClaim("password", user.getPassword())//password

.withExpiresAt(expireDate) //超时设置,设置过期的日期

.withIssuedAt(new Date()) //签发时间

.sign(Algorithm.HMAC256(SECRET)); //SECRET加密

return token;

}

/**

* 校验token并解析token

*/

public static Map<String, Claim> verifyToken(String token) {

DecodedJWT jwt = null;

try {

JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();

jwt = verifier.verify(token);

//decodedJWT.getClaim("属性").asString() ?获取负载中的属性值

} catch (Exception e) {

logger.error(e.getMessage());

logger.error("token解码异常");

//解码异常则抛出异常

return null;

}

return jwt.getClaims();

}

}

JWT过滤器

/**

* JWT过滤器,拦截 /secure的请求

* JWT过滤器中进行token的校验和判断,token不合法直接返回,合法则解密数据并把数据放到request中供后续使用。

*

* 为了使过滤器生效,需要在启动类添加注解@ServletComponentScan(basePackages = "com.zhaoyang.config")。

*/

@Slf4j

@WebFilter(filterName = "JwtFilter", urlPatterns = "/secure/*")

public class JwtFilter implements Filter

{

@Override

public void init(FilterConfig filterConfig) throws ServletException {

}

@Override

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

final HttpServletRequest request = (HttpServletRequest) req;

final HttpServletResponse response = (HttpServletResponse) res;

response.setCharacterEncoding("UTF-8");

//获取 header里的token

final String token = request.getHeader("authorization");

if ("OPTIONS".equals(request.getMethod())) {

response.setStatus(HttpServletResponse.SC_OK);

chain.doFilter(request, response);

}

// Except OPTIONS, other request should be checked by JWT

else {

if (token == null) {

response.getWriter().write("没有token!");

return;

}

Map<String, Claim> userData = JwtUtil.verifyToken(token);

if (userData == null) {

response.getWriter().write("token不合法!");

return;

}

Integer id = userData.get("id").asInt();

String userName = userData.get("userName").asString();

String password= userData.get("password").asString();

//拦截器 拿到用户信息,放到request中

request.setAttribute("id", id);

request.setAttribute("userName", userName);

request.setAttribute("password", password);

chain.doFilter(req, res);

}

}

@Override

public void destroy() {

}

}

登录Controller

/**

* 登录Controller

* LoginController进行登录操作,登录成功后生产token并返回。

*/

@Slf4j

@RestController

public class LoginController

{

static Map<Integer, User> userMap = new HashMap<>();

static {

//模拟数据库

User user1 = new User(1,"张三","123456");

userMap.put(1, user1);

User user2 = new User(2,"李四","123123");

userMap.put(2, user2);

}

/**

* 模拟用户 登录

*/

@RequestMapping("/login")

public String login(User user)

{

for (User dbUser : userMap.values()) {

if (dbUser.getUserName().equals(user.getUserName()) && dbUser.getPassword().equals(user.getPassword())) {

log.info("登录成功!生成token!");

String token = JwtUtil.createToken(dbUser);

return token;

}

}

return "";

}

}

携带jwt才能访问

/**

*需要登录后携带JWT才能访问

* SecureController中的请求会被JWT过滤器拦截,合法后才能访问。

?*/

@Slf4j

@RestController

public class SecureController

{

????/**

*查询 用户信息,登录后携带JWT才能访问

?????*/

????@RequestMapping("/secure/getUserInfo")

????public String login(HttpServletRequest request) {

????????Integer id = (Integer) request.getAttribute("id");

????????String userName = request.getAttribute("userName").toString();

????????String password= request.getAttribute("password").toString();

return "当前用户信息id=" + id + ",userName=" + userName+ ",password=" + password;

????}

}

启动类

@SpringBootApplication

@ServletComponentScan(basePackages = "com.zhaoyang.config")

public class SsmWebApplication {

public static void main(String[] args) {

SpringApplication.run(SsmWebApplication.class, args);

}

}

接口测试

测试分两步,首先访问登录接口,登录成功后获取token,然后拿着token在访问查询用户信息接口。

JWT案例二,第2张
JWT案例二,第3张

https://www.xamrdz.com/backend/3k21926073.html

相关文章: