1、判断提交信息的有效性
2、判断用户及密码正确性
3、生成token添加或更新数据库
4、返回token信息给客户端
1、获得客户端的token信息
2、对比客户端token数据库token信息
3、判断客户端token超时
4、判断放行与拦截
io.jsonwebtoken
jjwt
0.7.0
token表保存信息与userid
User实体类:
public class User {
private int userid;
private String name,password;
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [userid=" + userid + ", name=" + name + ", password=" + password + "]";
}
}
Token实体类:
public class Token {
private int tokenid,userid,buildtime;
private String token;
public int getTokenid() {
return tokenid;
}
public void setTokenid(int tokenid) {
this.tokenid = tokenid;
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public int getBuildtime() {
return buildtime;
}
public void setBuildtime(int buildtime) {
this.buildtime = buildtime;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
@Override
public String toString() {
return "Token [tokenid=" + tokenid + ", userid=" + userid + ", buildtime=" + buildtime + ", token=" + token + "]";
}
}
顺便来个Result信息类:
public class Result {
private boolean flag=false;
private String msg="";
private String token="";
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
@Override
public String toString() {
return "TokenResult [flag=" + flag + ", msg=" + msg + ", token=" + token + "]";
}
}
用户Mapper:
import org.apache.ibatis.annotations.Mapper;
import com.dahao.bean.User;
@Mapper
public interface UserMapper {
void addUser(User user);
void updataUser(User user);
User findByUserId(int id);
User findByUserName(String name);
}
Token Mapper:
import org.apache.ibatis.annotations.Mapper;
import com.dahao.bean.Token;
import com.dahao.bean.User;
@Mapper
public interface TokenMapper {
void addToken(Token token);
void updataToken(Token token);
Token findByUserId(int userid);
}
public class TokenInterceptor implements HandlerInterceptor {
@Autowired
private TokenMapper TokenMapper;
//提供查询
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {}
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {}
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
//普通路径放行
if ("/API/yanzheng".equals(arg0.getRequestURI()) || "/API/login".equals(arg0.getRequestURI())) {
return true;}
//权限路径拦截
arg1.setCharacterEncoding("UTF-8");
PrintWriter resultWriter=arg1.getWriter();
final String headerToken=arg0.getHeader("XW-Token");
//判断请求信息
if(null==headerToken||headerToken.trim().equals("")){
resultWriter.write("你没有token,需要登录");
return false;
}
//解析Token信息
try {
Claims claims = Jwts.parser().setSigningKey("dahao").parseClaimsJws(headerToken).getBody();
String tokenUserId=(String)claims.get("userid");
int itokenUserId=Integer.parseInt(tokenUserId);
//根据客户Token查找数据库Token
Token myToken=TokenMapper.findByUserId(itokenUserId );
//数据库没有Token记录
if(null==myToken) {
resultWriter.write("我没有你的token?,需要登录");
return false;
}
//数据库Token与客户Token比较
if( !headerToken.equals(myToken.getToken()) ){
resultWriter.write("你的token修改过?,需要登录");
return false;
}
//判断Token过期
Date tokenDate=(Date)claims.getExpiration();
int chaoshi=(int)(new Date().getTime()-tokenDate.getTime())/1000;
if(chaoshi>60*60*24*3){
resultWriter.write("你的token过期了?,需要登录");
return false;
}
} catch (Exception e) {
e.printStackTrace();
resultWriter.write("反正token不对,需要登录");
return false;
}
//最后才放行
return true;
}
}
@Configuration
public class TokenConfiguration extends WebMvcConfigurerAdapter{
@Bean
TokenInterceptor tokenInterceptor() {
return new TokenInterceptor();
// 这个方法才能在拦截器中自动注入查询数据库的对象
}
@Override
public void addInterceptors(InterceptorRegistry registry ){
registry.addInterceptor(tokenInterceptor()).addPathPatterns("/API/**");
//配置生成器:添加一个拦截器,拦截路径为API以后的路径
}
}
@Controller
//可以换成@RestController
@RequestMapping("/API/")
//方便拦截API路径下的URL
public class MainControler {
@Autowired
private UserMapper userMapper;
@Autowired
private TokenMapper tokenmapper;
@RequestMapping("/index")
public String showindex() {
return "index";
}
@RequestMapping("/login")
public String showlogin() {
return "login";
}
@ResponseBody
@RequestMapping("/yanzheng")
public Result yanzheng(User resqUser, HttpServletRequest request) {
//创建返回信息对象
Result result = new Result();
//判断用户信息为空
if ("".equals(resqUser.getName()) || "".equals(resqUser.getPassword())) {
result.setMsg("传入的用户名/密码为空!");
return result;
}
//根据客户用户名查找数据库的usre对象
User myUser = userMapper.findByUserName(resqUser.getName());
//判断用户不存在
if (null == myUser) {
result.setMsg("用户不存在");
return result;
}
//判断用户不存在
if (!resqUser.getPassword().equals(myUser.getPassword())) {
result.setMsg("密码不正确");
return result;
}
//根据数据库的用户信息查询Token
Token token = tokenmapper.findByUserId(myUser.getUserid());
//为生成Token准备
String TokenStr = "";
Date date = new Date();
int nowtime = (int) (date.getTime() / 1000);
//生成Token
TokenStr = creatToken(myUser, date);
if (null == token) {
//第一次登陆
token = new Token();
token.setToken(TokenStr);
token.setBuildtime(nowtime);
token.setUserid(myUser.getUserid());
tokenmapper.addToken(token);
}else{
//登陆就更新Token信息
TokenStr = creatToken(myUser, date);
token.setToken(TokenStr);
token.setBuildtime(nowtime);
tokenmapper.updataToken(token);
}
//返回Token信息给客户端
result.setFlag(true);
result.setMsg("登录成功");
result.setToken(TokenStr);
return result;
}
//生成Token信息方法(根据有效的用户信息)
private String creatToken(User user, Date date) {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT") // 设置header
.setHeaderParam("alg", "HS256").setIssuedAt(date) // 设置签发时间
.setExpiration(new Date(date.getTime() + 1000 * 60 * 60 * 24 * 3))
.claim("userid",String.valueOf(user.getUserid()) ) // 设置内容
.setIssuer("lws")// 设置签发人
.signWith(signatureAlgorithm, "dahao"); // 签名,需要算法和key
String jwt = builder.compact();
return jwt;
}
}