Token是密码学中的一个概念,可以用作身份验证凭证。在计算机领域中,token可以是一个字符串,用于标识用户的身份和权限。当用户进行身份验证时,他们通常会收到一个token,以便在将来的请求中用作凭证。
在互联网应用程序中,token通常用于实现单点登录(Single Sign-On),这样用户只需通过一次身份验证就可以访问多个应用。当用户登录成功后,应用服务器会生成一个token,并将其保存在用户的浏览器中,例如通过cookie或localStorage。
每当用户访问受保护的资源时,应用服务器会要求用户提供token,以验证其身份。服务器会通过对token进行验证来确定用户的身份和权限。
常见的token类型有JWT(JSON Web Token)和OAuth token。JWT是一种开放的标准,定义了在网络上以JSON格式传输信息的一种方式,可以用于在应用程序间安全地传输信息。OAuth token则用于授权和认证,允许用户将其身份验证信息共享给其他应用。
总之,Token是一种用于身份验证和授权的凭证,在网络应用程序中起到了重要的作用。
需要的三个工具类
package com.dc.utils;
import com.alibaba.druid.util.StringUtils;
import io.jsonwebtoken.*;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import java.util.Date;
@Data
@Component
@ConfigurationProperties(prefix = "jwt.token")
public class JwtHelper {
private long tokenExpiration; //有效时间,单位毫秒 1000毫秒 == 1秒
private String tokenSignKey; //当前程序签名秘钥
//生成token字符串
public String createToken(Long userId) {
// System.out.println("tokenExpiration = " + tokenExpiration);
// System.out.println("tokenSignKey = " + tokenSignKey);
String token = Jwts.builder()
.setSubject("YYGH-USER")
.setExpiration(new Date(System.currentTimeMillis() + tokenExpiration*1000*60)) //单位毫秒
.claim("userId", userId)
.signWith(SignatureAlgorithm.HS512, tokenSignKey)
.compressWith(CompressionCodecs.GZIP)
.compact();
return token;
}
//从token字符串获取userid
public Long getUserId(String token) {
if(StringUtils.isEmpty(token)) return null;
Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
Claims claims = claimsJws.getBody();
Integer userId = (Integer)claims.get("userId");
return userId.longValue();
}
//判断token是否有效
public boolean isExpiration(String token){
try {
boolean isExpire = Jwts.parser()
.setSigningKey(tokenSignKey)
.parseClaimsJws(token)
.getBody()
.getExpiration().before(new Date());
//没有过期,有效,返回false
return isExpire;
}catch(Exception e) {
//过期出现异常,返回true
return true;
}
}
}
package com.dc.utils;
/**
* 全局统一返回结果类
*/
public class Result<T> {
// 返回码
private Integer code;
// 返回消息
private String message;
// 返回数据
private T data;
public Result(){}
// 返回数据
protected static <T> Result<T> build(T data) {
Result<T> result = new Result<T>();
if (data != null)
result.setData(data);
return result;
}
public static <T> Result<T> build(T body, Integer code, String message) {
Result<T> result = build(body);
result.setCode(code);
result.setMessage(message);
return result;
}
public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) {
Result<T> result = build(body);
result.setCode(resultCodeEnum.getCode());
result.setMessage(resultCodeEnum.getMessage());
return result;
}
/**
* 操作成功
* @param data baseCategory1List
* @param
* @return
*/
public static<T> Result<T> ok(T data){
Result<T> result = build(data);
return build(data, ResultCodeEnum.SUCCESS);
}
public Result<T> message(String msg){
this.setMessage(msg);
return this;
}
public Result<T> code(Integer code){
this.setCode(code);
return this;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
package com.dc.utils;
/**
* 统一返回结果状态信息类
*
*/
public enum ResultCodeEnum {
SUCCESS(200,"success"),
USERNAME_ERROR(501,"usernameError"),
PASSWORD_ERROR(503,"passwordError"),
NOTLOGIN(504,"notLogin"),
USERNAME_USED(505,"userNameUsed");
private Integer code;
private String message;
private ResultCodeEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public String getMessage() {
return message;
}
}
pom文件中引入依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
yaml文件配置
#jwt配置
jwt:
token:
tokenExpiration: 120 #有效时间,单位分钟
tokenSignKey: dc123456 #当前程序签名秘钥 自定义
Controller接收请求,然后调用对应的service接口,再具体实现类中实现
@Override
public Result login(Weblogin weblogin) {
// System.out.println(weblogin);
LambdaQueryWrapper<Weblogin> lambdaQueryWrapper=new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(Weblogin::getUsername,weblogin.getUsername());
Weblogin user=webloginMapper.selectOne(lambdaQueryWrapper);
//账号不存在
if(user==null){
return Result.build(null, ResultCodeEnum.USERNAME_ERROR);//返回501异常
}
//密码不为空且密码正确(密码进行了加密)
if(!StringUtils.isEmpty(weblogin.getPassword())&&
MD5Util.encrypt(weblogin.getPassword()).equals(user.getPassword())){
//登陆成功
//根据用户id生成token
String token=jwtHelper.createToken(user.getUserid());
//将token封装到Result中
Map data=new HashMap();
data.put("token",token);
return Result.ok(data);
}
//密码错误
return Result.build(null,ResultCodeEnum.PASSWORD_ERROR);
}
前端将返回的token进行存储
submit() {
getMenu(this.form).then((data) => {
if (data.data.code == 501) {
this.$message.error('用户不存在');
} else if (data.data.code == 503) {
this.$message.error('密码错误');
} else if (data.data.code == 200) {
this.$message({
message: '登陆成功',
type: 'success'
});
Cookie.set("token",data.data.data.token)
this.$router.push('/home')
}
})
}