写点什么

JWT 单点登录,小甲鱼数据结构百度云

  • 2021 年 11 月 10 日
  • 本文字数:2601 字

    阅读完需:约 9 分钟

  1. 用户登录,发送账号密码

  2. 服务的认证,通过后根据 secret 生成 token

  3. 将生成的 token 返回给浏览器

  4. 用户每次请求携带 token

  5. 服务端利用公钥解读 jwt 签名,判断签名有效后,从 Payload 中获取用户信息

  6. 处理请求,返回响应结果


实现 JWT 单点登录


=======================================================================


1)创建登录鉴权服务,引入依赖


<dependency>


<groupId>org.apache.commons</groupId>


<artifactId>commons-lang3</artifactId>


<version>3.4</version>


</dependency>


<dependency>


<groupId>io.jsonwebtoken</groupId>


<artifactId>jjwt</artifactId>


<version>0.9.0</version>


</dependency>


<dependency>


<groupId>joda-time</groupId>


<artifactId>joda-time</artifactId>


<version>2.9.9</version>


</dependency>


2)配置文件的工具类


/**


  • 读取配置文件的配置类


*/


@Data


@Configuration


//读取配置文件的注解


@ConfigurationProperties(prefix = "blb.jwt")


public class JwtProperties {


private String secret;//秘钥


private String pubKeyPath;//公钥路径


private String priKeyPath;//私钥路径


private String cookieName;//cookie 名称


private Integer expire;//cookie 过期时间


private Integer cookieMaxAge;//cookie 生命周期


private PublicKey publicKey;//公钥


private PrivateKey privateKey;//私钥


//在构造方法之后自动执行


@PostConstruct


public void init(){


File pubKey = new File(pubKeyPath);


File priKey = new File(priKeyPath);


try {


//判断公钥和私钥如果不存在就创建


if (!priKey.exists() || !pubKey.exists()) {


//创建公钥和私钥文件


RsaUtils.generateKey(this.pubKeyPath, this.priKeyPath, this.secret);


}


//读取公钥和私钥内容


this.publicKey = RsaUtils.getPublicKey(this.pubKeyPath);


this.privateKey = RsaUtils.getPrivateKey(this.priKeyPath);


}catch (Exception ex){


ex.printStackTrace();


throw new RuntimeException(ex);


}


}


}


application.properties


#秘钥


blb.jwt.secret=chenheng0611@#$%


#公钥路径


blb.jwt.pubKeyPath=D:\java_code\pub.rsa


#私钥路径


blb.jwt.priKeyPath=D:\java_code\pri.rsa


#cookie 名称


blb.jwt.cookieName=token


#cookie 过期时间


blb.jwt.expire=30


#cookie 生命周期


blb.jwt.cookieMaxAge=1800


UserService


@Service


public class UserServiceImpl extends ServiceImpl<UserMapper, UserInfo> implements IUserService {


@Override


public UserInfo login(String username, String password) {


//查询用户


UserInfo user = this.getOne(new QueryWrapper<UserInfo>().lambda().eq(UserInfo::getUsername, username));


if(user == null){


return null;


}


//将密码加密加盐后进行匹配


String encrypt = Md5Utils.encrypt(password, user.getSalt());


if(encrypt.equals(user.getPassword())){


return user;


}


return null;


}


}


UserController


/**


  • 登录验证控制器


*/


@RestController


@RequestMapping("/user")


public class UserController {


@Autowired


private IUserService userService;


@Autowired


private JwtProperties properties;


@PostMapping("/login")


public JsonResult<UserInfo> login(HttpServletRequest request, HttpServletResponse response) throws Exception {


String username = request.getParameter("username");


String password = request.getParameter("password");


UserInfo info = userService.login(username, password);


if(info != null){


//验证通过,将用户加密为 token


String token = JwtUtils.generateToken(info, properties.getPrivateKey(), properties.getExpire());


//保存 token 到 cookie 中


CookieUtils.setCookie(request,response,properties.getCookieName(),token,


properties.getCookieMaxAge(),null,true);


return new JsonResult<>(1,info);


}


return new JsonResult<>(0,null);


}


}


登录页面


<template>


<el-card style="width: 480px">


<span style="color:red">{{msg}}</span>


<el-form v-model="form">


<el-input v-model="form.username" placeholder="请输入账号"></el-input>


<el-input type="password" v-model="form.password" placeholder="请输入密码"></el-input>


<el-button @click="login">登录</el-button>


</el-form>


</el-card>


</template>


<script>


export default {


name: "Login",


data(){


return{


msg:"",


form:{username:"",password:""}


}


},


methods:{


login(){


this.qs.stringify(this.form))


.then(res => {


if(res.data.code == 1){


this.$message.info("登录成功");


this.$router.push("/index");


}else{


this.msg = "账号或密码错误";


}


});


}


}


}


</script>


解决 cookie 写入失败的问题


原因 1:出现跨域,导致 Cookie 不能写入


1)CORS 的配置



2)axios 的配置



原因 2:Nginx 转发域名不一致的问题


Nginx 转发配置 : proxy_set_header Host $host;



原因 3:zuul 的敏感头过滤


关闭敏感头过滤



解决 Cookie 写入问题后,将公钥复制到网关服务器上,在网关中进行 token 解析实现统一的访问鉴权



网关判断用户登录状态


1)配置白名单,直接通过不进行登录验证


2)创建过滤器 ZuulFilter


3)过滤到白名单就直接放行


4)非白名单的请求,获得 cookie 中的 token,解析 token


5)如果解析成功,放行,解析失败,就进行拦截


网关的配置文件工具类


@Data


@Configuration


//读取配置文件的注解


@ConfigurationProperties(prefix = "blb.jwt")


public class JwtProperties {


private


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


List<String> whiteList;//白名单


private String pubKeyPath;//公钥路径


private String cookieName;//cookie 名称


private PublicKey publicKey;//公钥


//在构造方法之后自动执行


@PostConstruct


public void init(){


try {


//读取公钥内容


this.publicKey = RsaUtils.getPublicKey(this.pubKeyPath);


}catch (Exception ex){


ex.printStackTrace();


throw new RuntimeException(ex);


}


}


}


application.properties

白名单

blb.jwt.whiteList=/api/auth-api

公钥路径

blb.jwt.pubKeyPath=D:\java_code\pub.rsa

cookie 名称

blb.jwt.cookieName=token


鉴权过滤器


/**


  • 登录鉴权的过滤器


*/


@Component


public class AuthFilter extends ZuulFilter {


@Autowired


private JwtProperties properties;


@Override

评论

发布
暂无评论
JWT单点登录,小甲鱼数据结构百度云