首先是基于springboot,来操作的简单的创建项目跳过直接上正文
1.创建一个项目
我们先创建一个项目,
实现实体类,dao,service,controller
先实现登录业务,
@PostMapping("login.do") public String login(String username, String password){return "登录"}
导入依赖实现swagger
<!--导入swagger --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> <exclusions> <exclusion> <groupId>io.swagger</groupId> <artifactId>swagger-models</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.swagger</groupId> <artifactId>swagger-models</artifactId> <version>1.5.21</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>swagger-bootstrap-ui</artifactId> <version>1.9.6</version> </dependency>
配置文件
@Configuration //激活swagger配置 @EnableSwagger2 public class SwaggerConfig { //创建RestApi文档生成 @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() //指定扫描包的路径(必须) .apis(RequestHandlerSelectors.basePackage("xxx.controller"))//com.java2205.logindemo.controller扫描到controller .paths(PathSelectors.any()) .build(); } //api相关的信息说明 private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("Spring Boot中使用Swagger2构建RESTful API") .description("rest api 文档构建利器") .version("1.0") .build(); } }
创建返回的Vo
package com.java2205.logindemo.vo;
import lombok.Getter;
import lombok.Setter;
/**
*/
@Setter
@Getter
public class ResultVo {
public static final int SUCCESS = 20000;
public static final int FAIL = 40000;
int code;
String message;
Object data;
public static ResultVo success(String message,Object data){
ResultVo rd = new ResultVo();
rd.setData(data);
rd.setMessage(message);
rd.setCode(SUCCESS);
return rd;
}
public static ResultVo fail(String message,Object data){
ResultVo rd = new ResultVo();
rd.setCode(FAIL);
rd.setData(data);
rd.setMessage(message);
return rd;
}
}
更新登录
@PostMapping("login.do") public ResultVo login(String username, String password){ TUser loginUser = userService.login(username,password); return ResultVo.success("登录成功", ""); }
当我们登录成功以后要利用token拿去用户,所有要用JWT来实现
2.登录需要产生token来验证,
引入JWT来实现。
先导入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.3</version>
</dependency>
导入两个依赖来实现JWT的功能
创建一个JWTutli
public class JWTUtil {
//定义密钥
public static final String SECRET = "XASDAS";
//定义token的有效时间
public static final int EXPIRED = 10*1000;
//最大过期时间
public static final long EXPIREDMAX = 40*1000;
public static final String ACCOUNT ="account";
//创建toke,暂时弃用
public static String createToken(String account){
try {
//根据密码创建算法,secret是密钥,可以自定义
Algorithm algorithm = Algorithm.HMAC256(SECRET);
//创建token,Issuer是token的拥有人,可以自定义
String token = JWT.create()
.withClaim(ACCOUNT,account)
.withExpiresAt(new Date(System.currentTimeMillis()+EXPIRED))
.sign(algorithm);
return token;
} catch (JWTCreationException exception){
exception.printStackTrace();
throw exception;
}
}
//判断是token
public static boolean createTokens(String token){
return createTokens.containsKey(token);
}
//创建map缓存
public static Map<String,Object> createTokens=new HashMap<>();
//保持token和时间到map缓存中
public static void saveToken(String token,long time){
createTokens.put(token, time);
}
//更具token获取map缓存中的时间
public static Object getToken(String token){
return createTokens.get(token);
}
//获取当前时间
public static long currentTime(){
return System.currentTimeMillis();
}
//移除map缓存中的token
public static void remove(String token){
createTokens.remove(token);
}
//创建token实际运用版本
public static String createToken(String account,long currentTime){//传入账号和创建时间
try {
//根据密码创建算法,secret是密钥,可以自定义
Algorithm algorithm = Algorithm.HMAC256(SECRET);
//创建token,Issuer是token的拥有人,可以自定义
String token = JWT.create()
.withClaim(ACCOUNT,account)
.withExpiresAt(new Date(currentTime+EXPIRED))//token的有效期,
.sign(algorithm);
return token;
} catch (JWTCreationException exception){
exception.printStackTrace();
throw exception;
}
}
//验证token
public static boolean verify(String token){
try {
Algorithm algorithm = Algorithm.HMAC256(SECRET);
JWTVerifier verifier = JWT.require(algorithm)
.build(); //Reusable verifier instance
DecodedJWT jwt = verifier.verify(token);
return true;
} catch (JWTVerificationException exception){
//Invalid signature/claims
exception.printStackTrace();
throw exception;
}
// return false;
}
//解析
public static String getAccount(String token){
try {
DecodedJWT jwt = JWT.decode(token);
//获取自定义参数
String account = jwt.getClaim(ACCOUNT).asString();
return account;
} catch (JWTDecodeException exception){
//Invalid token
exception.printStackTrace();
throw exception;
}
}
}
然后跟新登录
@RestController
public class LoginController {
@Autowired
TUserServiceImpl userService;
@PostMapping("login.do")
public ResultVo login(String username, String password){
TUser loginUser = userService.login(username,password);
//生成token并且返回
//生成token并且返回
long times=JWTUtil.currentTime();
String token = JWTUtil.createToken(loginUser.getUname(),times);
JWTUtil.saveToken(token,times);
//用来在swagger中能看见map中的token,
Map<String,Object> map = new HashMap<>();
map.put("token",token);
return ResultVo.success("登录成功", map);
}
}
创建一个新的操作
@RestController
@RequestMapping("tUser")
public class TUserController {
@Autowired
TUserService userService;
@ApiOperation(value = "获取当前登录用户的信息")
@GetMapping("info")
public ResultVo info(){
//获取token
TUser loginUser = MyContextHolder.get();
return ResultVo.success("查看",loginUser);
}
}
登录以后,我们能进行其他操作,比如能通过info获取用户,通过验证token是否失效来获取。
将token存在ThreadLocal中
public class MyContextHolder {
static ThreadLocal<TUser> userHolder = new ThreadLocal<>();
public static void set(TUser user){
userHolder.set(user);
}
public static TUser get(){
return userHolder.get();
}
}
写一个过滤器,当访问其他页面的时候判断是否登录实现,验证token
package com.java2205.logindemo.filter;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.java2205.logindemo.common.MyContextHolder;
import com.java2205.logindemo.entity.TUser;
import com.java2205.logindemo.service.TUserService;
import com.java2205.logindemo.util.JWTUtil;
import com.java2205.logindemo.util.ResponseUtil;
import com.java2205.logindemo.vo.ResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
*
*/
@WebFilter("/tUser/*")
public class JWTAuthFilter implements Filter {
@Autowired
TUserService userService;
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//从请求头中获取token
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
String token = httpServletRequest.getHeader("Authorization");
try{
if(JWTUtil.verify(token)) {
//成功了,从token中获取用户的信息
String account = JWTUtil.getAccount(token);
TUser loginuser = userService.getOne(new QueryWrapper<TUser>().eq("uname", account));
MyContextHolder.set(loginuser);
filterChain.doFilter(servletRequest,servletResponse);
}else{
ResponseUtil.writeJson(httpServletResponse,ResultVo.fail("用户没有登录,请先登录",null));
}
}catch (Exception e){
if(e instanceof TokenExpiredException){
//过期了
String account = JWTUtil.getAccount(token);
if(JWTUtil.createTokens(token)) {
Long time = (Long) JWTUtil.getToken(token);
if ((time + JWTUtil.EXPIREDMAX)-(System.currentTimeMillis() ) >= 0) {
//换新的token,先清除老token
JWTUtil.remove(token);
String newToken = JWTUtil.createToken(account);
//新的时间
JWTUtil.saveToken(newToken, JWTUtil.currentTime());
//将新的token放入到头部中
httpServletResponse.setHeader("token", newToken);
//成功了,从token中获取用户的信息
TUser loginuser = userService.getOne(new QueryWrapper<TUser>().eq("uname", account));
MyContextHolder.set(loginuser);
//放行
filterChain.doFilter(servletRequest, servletResponse);
}else {
ResponseUtil.writeJson(httpServletResponse,ResultVo.fail("token过期,请重新登录",null));
}
}else {
ResponseUtil.writeJson(httpServletResponse,ResultVo.fail("token过期",null));
}
}else{
ResponseUtil.writeJson(httpServletResponse,ResultVo.fail("无效token,请重新登录",null));
}
}
}
}
写一个返回josn格式
package com.java2205.logindemo.util;
import com.alibaba.fastjson.JSONObject;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
*
*/
public class ResponseUtil {
public static void writeJson(HttpServletResponse response,Object data){
response.setCharacterEncoding("utf-8");
response.setContentType("application/json");
try {
response.getWriter().write(JSONObject.toJSONString(data));
} catch (IOException e) {
e.printStackTrace();
}
}
}
写一个异常处理
@RestControllerAdvice
public class MyExceptionHandler {
@ExceptionHandler(RuntimeException.class)
public ResultVo handler(RuntimeException e){
return ResultVo.fail(e.getMessage(),null);
}
}
启动类加入
@SpringBootApplication
@ServletComponentScan("com.java2205.logindemo")
public class LogindemoApplication {
public static void main(String[] args) {
SpringApplication.run(LogindemoApplication.class, args);
}
}
完全目录