当前位置:   article > 正文

Java + sa-token统一身份认证开发笔记_sa-token 实现统一身份认证

sa-token 实现统一身份认证

官网地址:Sa-Token

统一认证服务端

直接用的官网的demo,稍加改动,因为要前后端分离,加了一个H5Controller,官网也有详细介绍,这一部分不难,照着做就行了

配置文件

  1. # Sa-Token 配置
  2. sa-token:
  3. # ------- SSO-模式一相关配置 (非模式一不需要配置)
  4. # cookie:
  5. # 配置 Cookie 作用域
  6. # domain: stp.com
  7. # ------- SSO-模式二相关配置
  8. sso:
  9. # Ticket有效期 (单位: 秒),默认五分钟
  10. ticket-timeout: 300
  11. # 所有允许的授权回调地址
  12. allow-url: "*"
  13. # ------- SSO-模式三相关配置 (下面的配置在使用SSO模式三时打开)
  14. # 是否打开模式三
  15. is-http: true
  16. sign:
  17. # API 接口调用秘钥
  18. secret-key: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
  19. # ---- 除了以上配置项,你还需要为 Sa-Token 配置http请求处理器(文档有步骤说明)

业务服务端

因为要用到跨redis,跨域,所以要用到他们的client3模式。

配置文件

  1. sa-token:
  2. # SSO-相关配置
  3. sso:
  4. # SSO-Server端 统一认证地址
  5. auth-url: http://localhost:9000/sso/auth
  6. #auth-url: http://127.0.0.1:5500/sso-login.html
  7. # 使用 Http 请求校验ticket (模式三)
  8. is-http: true
  9. # SSO-Server端 ticket校验地址
  10. check-ticket-url: http://localhost:9000/sso/checkTicket
  11. # 单点注销地址
  12. slo-url: http://localhost:9000/sso/signout
  13. # 查询数据地址
  14. get-data-url: http://localhost:9000/sso/getData
  15. sign:
  16. # API 接口调用秘钥
  17. secret-key: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor

上面是demo,整合到自己的业务服务端

将自己的token一并返回给前端

  1. @RequestMapping("/sso/doLoginByTicket")
  2. public SaResult doLoginByTicket(String ticket) {
  3. Object loginId = SaSsoProcessor.instance.checkTicket(ticket, "/sso/doLoginByTicket");
  4. if(loginId != null) {
  5. StpUtil.login(loginId);
  6. String token = jwtConfig.createToken(loginId.toString()) ;
  7. Map<String, Object> resultMap = new HashMap<>();
  8. resultMap.put("satoken", StpUtil.getTokenValue());
  9. resultMap.put("token", token);
  10. return SaResult.data(resultMap);
  11. }
  12. return SaResult.error("无效ticket:" + ticket);
  13. }

提供一个api获取登录后的相关信息

  1. @RequestMapping("/loginBySso")
  2. public Result<?> loginBySso(HttpServletRequest request) {
  3. String token = request.getHeader("token");
  4. String userId = jwtConfig.getUsernameFromToken(token);
  5. QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
  6. queryWrapper.eq("id", userId);
  7. SysUser sysUser = sysUserService.getOne(queryWrapper, false);
  8. if (sysUser != null) {
  9. if(sysUser.getLockFlag()!=null && sysUser.getLockFlag().equals("1")){
  10. return Result.error("用户已被锁定,请联系管理员解锁!",sysUser);
  11. }
  12. if(!"0".equals(sysUser.getStatus())){
  13. if(DBsUserConstant.Status.SECPERIOD.equals(sysUser.getStatus())){
  14. return Result.error("用户账号已删除,请联系管理员!",sysUser);
  15. }else {
  16. return Result.error("用户账号正在申请中,请联系管理员审核!", sysUser);
  17. }
  18. }
  19. LoginModel model = getUserInfo(sysUser);
  20. return Result.ok(JSON.toJSONString(model));
  21. } else {
  22. return Result.error("无此用户!");
  23. }
  24. }

业务客户端

参考的这个demo

整合到自己的业务客户端

修改路由配置,非常关键

  1. router.beforeEach(async (to, from, next) => {
  2. //debugger;
  3. let token = sessionStorage.getItem('token');
  4. const url = new URL(window.location.href)
  5. const params = getParams(url);
  6. let ticket = params.ticket;
  7. if (ticket && isEmpty(token)) {
  8. //debugger;
  9. //有票据拿token
  10. const ticketRes = await ssoLoginByTicket({ticket: ticket})
  11. sessionStorage.setItem('token', ticketRes.data.data.token)
  12. localStorage.setItem('satoken', ticketRes.data.data.satoken)
  13. const res = await userLoginBySso()
  14. afterLogin(res);
  15. config.configData.sso_enable = true
  16. next({ path: desktopUrl() })
  17. return false
  18. } else {
  19. if (to.path === '/sso') {
  20. config.configData.sso_enable = true
  21. }
  22. //无票据,进入登录页面
  23. if (config.configData.sso_enable && isEmpty(token)) {
  24. const ssoUrlRes = await ssoAuthUrl({clientLoginUrl: location.origin+'/'})
  25. location.href = ssoUrlRes.data.data
  26. return false;
  27. }
  28. //如果直接跳登录页面,不管是不是sso都眺
  29. if (to.path === '/login') {
  30. next()
  31. return false
  32. }
  33. //跳首页时直接决定是登录页还是桌面
  34. if (to.path === '/' || to.path === '/sso') {
  35. if (isEmpty(token)) {
  36. next("login")
  37. } else {
  38. next("desktop")
  39. }
  40. return false
  41. }
  42. //不能反着跳
  43. if (to.path === "/" && from.path === "/login") {
  44. return false;
  45. }
  46. }
  47. next()
  48. })

相关api

  1. import Vue from 'vue'
  2. import {ajax} from '@/utils/httputils'
  3. import config from '@/config/index.js'
  4. const API_URL = config.configData.api_url
  5. const http = (method, url, data) => {
  6. return new Promise((resolve, reject) => {
  7. return ajax(method, url, data).then((res) => {
  8. if (res.data.code == 200) {
  9. resolve(res)
  10. } else {
  11. reject(res)
  12. }
  13. }).catch(error => reject(error))
  14. })
  15. }
  16. /**
  17. * server
  18. * /sso/auth
  19. * /sso/checkTicket
  20. * /sso/signout
  21. * /sso/userinfo
  22. *
  23. * client
  24. * /sso/getSsoAuthUrl
  25. * /sso/doLoginByTicket
  26. * /sso/logout
  27. * /sso/logoutCall
  28. */
  29. export function ssoAuth(data) {
  30. return http('get', API_URL + "/sso/auth", data)
  31. }
  32. export function ssoCheckTicket(data) {
  33. return http('get', API_URL + "/sso/checkTicket", data)
  34. }
  35. export function ssoSignout(data) {
  36. return http('get', API_URL + "/sso/signout", data)
  37. }
  38. export function ssoUserInfo(data) {
  39. return http('get', API_URL + "/sso/userinfo", data)
  40. }
  41. export function ssoAuthUrl(data) {
  42. return http('get', API_URL + "/sso/getSsoAuthUrl", data)
  43. }
  44. export function ssoLoginByTicket(data) {
  45. return http('get', API_URL + "/sso/doLoginByTicket", data)
  46. }
  47. export function ssoLogout(data) {
  48. return http('get', API_URL + "/sso/logout", data)
  49. }
  50. export function ssoLogoutCall(data) {
  51. return http('get', API_URL + "/sso/logoutCall", data)
  52. }

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号