配置文件:
最主要是第一个依赖,后面不属于jsonwebtoken的依赖
controller:
@PostMapping("/login") public Result<TokenStatus> login(@RequestBody LoginVO loginVO, HttpServletRequest request) { Result<TokenStatus> result = new Result<>(); UserDO userDO = null; try { userDO = userService.getUser(loginVO, request); } catch (NirException e) { result.setCode(e.getCode()); result.setMsg(e.getMessage()); return result; } catch (Exception e) { result.setCode(NirExceptionEnum.GENERAL_EXCEPTION.getCode()); result.setMsg(e.getMessage()); return result; } TokenStatus tokenStatus = JwtUtil.createJwt(userDO.getId().toString(),userDO.getUsername()); result.setData(tokenStatus); result.setCode(ResultEnum.SUCCESS.getCode()); result.setMsg(ResultEnum.SUCCESS.getMsg()); return result; }
JwtUtil类
public class JwtUtil { public static final String KEY = "userlogin"; public static final Long FAILURE_TIME = 3600000L; public static TokenStatus createJwt(String id, String username){ TokenStatus tokenStatus = new TokenStatus(); long now = System.currentTimeMillis(); long exp = now + FAILURE_TIME; Date date = new Date(exp); JwtBuilder jwtBuilder = Jwts.builder().setId(id).setSubject(username) .setIssuedAt(new Date()).signWith(SignatureAlgorithm.HS256,KEY); jwtBuilder.setExpiration(date); String token = jwtBuilder.compact(); tokenStatus.setToken(token); tokenStatus.setExp(date); return tokenStatus; } public static Claims parseJwt(String token){ Claims claims = Jwts.parser().setSigningKey(KEY).parseClaimsJws(token).getBody(); return claims; } }
let param = { username: values.username, password: values.password, }; API.login(param) .then((res) => { const { code, msg, data} = res; if (code !== "200") { Message.error("登录失败,用户名或密码错误!"); } else { Message.success("登录成功!"); if(data.token&&data.exp){ document.cookie = "token="+ data.token+";expires="+new Date(data.exp).toGMTString(); } this.props.history.push('/home'); } }) .catch((err) => { Message.error(err + "登录失败!请重试!"); });
退出登录清除cookie中的token,跳转到登录页面
logout = () => { deleteCookie("token"); this.props.history.replace("/login"); }; export const deleteCookie = (name) => { var exp = new Date(); exp.setTime(exp.getTime()-1); var val = getCookie(name); if(val!=null){ document.cookie= name + "="+val+";expires="+exp.toGMTString(); } } export const getCookie = (name) => { var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)"); if(arr=document.cookie.match(reg)) return unescape(arr[2]); else return null; }
给每个请求添加请求头Authorization,加上token
headers: { "Content-Type": "application/json", 'Authorization': getCookie("token") , "withCredentials": true, },
import React from 'React'; import { Route, Redirect } from 'react-router-dom'; import { Message } from 'antd'; import { getCookie } from "../pages/home/Home"; const PrivateRoute = ({component: Component, ...props}) => { // 解构赋值 将 props 里面的 component 赋值给 Component return <Route {...props} render={(p) => { const token = getCookie("token"); if (token){ // 如果登录了, 返回正确的路由 if(props.path==='/login'){ return <Redirect to='/home'/> }else{ return <Component /> } } else { // 没有登录就重定向至登录页面 Message.error("你还未登录,请先登录") return <Redirect to='/login'/> } }}/> } export default PrivateRoute
使用方法:
<Route path="/login" component={Login}></Route> <Route path="/register" component={Register}></Route> <PrivateRoute path="/admin" component={Admin}></PrivateRoute> <PrivateRoute path="/home" component={Home}></PrivateRoute>
此处的过滤器采用javax.servlet.Filter的接口实现
@WebFilter(urlPatterns = {"/user/getUser","/record/*","/patient/*","/disease/*"}) public class TokenFilter implements Filter { @Autowired private UserDOMapper userMapper; @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse; String token = httpServletRequest.getHeader("Authorization"); try{ if(token==null || token.equals("null")){ throw new NirException(NirExceptionEnum.USER_UNLOGIN); }else{ UserDOExample example = new UserDOExample(); String username = JwtUtil.parseJwt(token).getSubject(); example.createCriteria().andUsernameEqualTo(username); List<UserDO> users = userMapper.selectByExample(example); if (CollectionUtils.isEmpty(users)) { throw new NirException(NirExceptionEnum.USER_UNLOGIN); }else{ filterChain.doFilter(servletRequest,servletResponse); } } }catch(NirException e){ Result<Void> result = new Result<>(); result.setCode(e.getCode()); result.setMsg(e.getMessage()); httpServletResponse.setHeader("content-type", "application/json;charset=utf-8"); httpServletResponse.setHeader("Access-Control-Allow-Origin","*"); httpServletResponse.setHeader("Access-Control-Allow-Methods","POST,OPTIONS"); httpServletResponse.setHeader("Access-Control-Allow-Credentials","true"); httpServletResponse.setHeader("Access-Control-Allow-Headers","Content-Type,WithCredentials,Authorization"); PrintWriter out = httpServletResponse.getWriter(); out.println(JSON.toJSONString(result)); } } @Override public void destroy() { } }
这样就实现了一个系统的的token登录功能。