大家好,又见面了,我是你们的朋友全栈君。
实现的效果是,在的客户端登录时会返回一个token用作客户端后续登录校验,登录之后客户端需要将token放在请求的head中,否则返回的登录失败。话不多说直接上代码。
1.JWT工具类
前面的文章有JWT的一个简单的示例,后来我对它进行了完善,代码如下:
package com.youyou.shiro.jwt;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.youyou.util.utils.DateUtil;
import org.apache.commons.lang3.StringUtils;
import java.util.Date;
/**
* @author youyou
* <br/>date 2019-01-09
*/
public class JwtUtil {
private static final String USERNAME = "username";
private static final String KEY = "123456qwe";
/**
* 过期时间(分钟)
*/
private static final int EXPIRATION_TIME = 5;
/**
* 生成token
*
* @param userName
* @return
* @author 刘朋
* <br/>date 2019-01-09
*/
public static String createToken(String userName) {
Algorithm algorithm = Algorithm.HMAC256(KEY);
Date expirationDate = DateUtil.addMinutes(DateUtil.getNow(), EXPIRATION_TIME);
//生成token
return JWT.create().withClaim(USERNAME, userName)
.withExpiresAt(expirationDate)
.sign(algorithm);
}
/**
* 获取用户名
*
* @param token
* @return
* @author 刘朋
* <br/>date 2019-03-08
*/
public static String getUsername(String token) {
return getValueByToken(token, USERNAME);
}
/**
* 获取token中的值
*
* @param token
* @param key
* @return
*/
public static String getValueByToken(String token, String key) {
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(KEY)).build();
DecodedJWT decode = verifier.verify(token);
return decode.getClaim(key).asString();
}
/**
* 校验是否过期,过期返回true
* @param token
* @return
* @author 刘朋
* <br/>date 2019-03-12
*/
public static boolean isExpires(String token){
if(StringUtils.isBlank(token)){
return true;
}
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(KEY)).build();
try {
verifier.verify(token);
}catch (JWTVerificationException e){
return true;
}
return false;
}
}
2.登录Controller
这里博主用的是MyBatisPlus,做的orm框架,有兴趣的话可以看一下前面的博文https://blog.csdn.net/lp840312696/article/details/83691915
package com.youyou.login.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.youyou.common.http.ResponseMessage;
import com.youyou.common.http.Result;
import com.youyou.login.entity.UserDO;
import com.youyou.login.service.LoginService;
import com.youyou.shiro.jwt.JwtUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Objects;
/**
* 登录接口
*
* @author 刘朋
* <br/>date 2019-03-12
*/
@Api(description = "登录接口")
@RestController
@RequestMapping("/login")
public class LoginController {
@Autowired
private LoginService service;
@ApiOperation(value = "登录")
@PostMapping("")
public ResponseMessage<String> login(String username, String password) {
if(StringUtils.isAnyBlank(username , password)){
return Result.error("用户名密码不能为空!");
}
QueryWrapper<UserDO> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name" ,username);
queryWrapper.eq("password" ,password);
UserDO userDO = service.querySingle(queryWrapper);
if(Objects.isNull(userDO)){
return Result.error("用户名密码错误!");
}
//生成一个token
String token = JwtUtil.createToken(username);
return Result.success(token);
}
}
3.创建过滤器
package com.youyou.login.config;
import com.youyou.login.filter.LoginFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 登录拦截配置
*
* @author 刘朋
* <br/>date 2019-03-21
*/
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean loginFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new LoginFilter());
registration.addUrlPatterns("/api/*");
registration.setName("LoginFilter");
//数越小越先执行
registration.setOrder(6);
return registration;
}
}
经过三步配置就已经完成了登录检验了,需要登录之后才能访问的接口需要以api开头。
4.配置swagger(这步不重要,如果没有用到swagger的话可以忽略)
如果大家用到了swagger的话一定会有这个问题,使用swagger测试的时候也需要传token进行登录校验,所以需要以下配置
package com.youyou.config;
import io.swagger.annotations.ApiOperation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket swaggerSpringMvcPlugin() {
return initDocket();
//简单的swagger配置
// return new Docket(DocumentationType.SWAGGER_2).select()
// .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).build();
}
/**
* 在swagger界面中每个接口添加个Authorization参数的录入框,用来做的登录校验
* @param
* @return
* @author 刘朋
* <br/>date 2019-03-25
*/
public static Docket initDocket() {
ParameterBuilder parameterBuilder = new ParameterBuilder();
List<Parameter> parameters = new ArrayList<>();
parameterBuilder.name("Authorization").description("token").modelRef(new ModelRef("string"))
.parameterType("header").required(false).build();
parameters.add(parameterBuilder.build());
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).build()
.globalOperationParameters(parameters);
}
}
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/106453.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...