mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-10-21 02:57:23 +08:00
完善文档
This commit is contained in:
Binary file not shown.
@@ -5,6 +5,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.spring.SaTokenSetup;
|
||||
|
||||
@SaTokenSetup // 标注启动 sa-token
|
||||
@@ -13,6 +14,12 @@ public class SaTokenDemoApplication {
|
||||
|
||||
public static void main(String[] args) throws JsonProcessingException {
|
||||
SpringApplication.run(SaTokenDemoApplication.class, args); // run-->
|
||||
System.out.println("启动成功:sa-token配置如下:" + SaTokenManager.getConfig());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
//package com.pj.satoken;
|
||||
//
|
||||
//import org.springframework.context.annotation.Bean;
|
||||
//import org.springframework.context.annotation.Configuration;
|
||||
//import org.springframework.context.annotation.Primary;
|
||||
//
|
||||
//import cn.dev33.satoken.config.SaTokenConfig;
|
||||
//
|
||||
///**
|
||||
// * sa-token代码方式进行配置
|
||||
// */
|
||||
//@Configuration
|
||||
//public class MySaTokenConfig {
|
||||
//
|
||||
// // 获取配置Bean
|
||||
// @Primary
|
||||
// @Bean(name="MySaTokenConfig")
|
||||
// public SaTokenConfig getSaTokenConfig() {
|
||||
// SaTokenConfig config = new SaTokenConfig();
|
||||
// config.setTokenName("satoken"); // token名称(同时也是cookie名称)
|
||||
// config.setTimeout(30 * 24 * 60 * 60); // token有效期,单位s 默认30天,-1为永不过期
|
||||
// config.setIsShare(true); // 在多人登录同一账号时,是否共享会话(为true时共用一个,为false时新登录挤掉旧登录)
|
||||
// config.setIsReadHead(true); // 是否在cookie读取不到token时,继续从请求header里继续尝试读取
|
||||
// config.setIsReadBody(true); // 是否在cookie读取不到token时,继续从请求header里继续尝试读取
|
||||
// config.setIsV(true); // 是否在初始化配置时打印版本字符画
|
||||
// return config;
|
||||
// }
|
||||
//
|
||||
//}
|
@@ -13,9 +13,10 @@ import cn.dev33.satoken.stp.StpInterface;
|
||||
@Component // 打开此注解,保证此类被springboot扫描,即可完成sa-token的自定义权限验证扩展
|
||||
public class StpCustom implements StpInterface {
|
||||
|
||||
// 返回一个账号所拥有的权限码集合
|
||||
@Override
|
||||
public List<Object> getPermissionCodeList(Object login_id, String login_key) {
|
||||
List<Object> list = new ArrayList<Object>();
|
||||
List<Object> list = new ArrayList<Object>(); // 本list仅做模拟,实际项目中要根据具体业务逻辑来查询权限
|
||||
list.add("101");
|
||||
list.add("user-add");
|
||||
list.add("user-delete");
|
||||
|
@@ -4,7 +4,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import cn.dev33.satoken.session.SaSessionUtil;
|
||||
import cn.dev33.satoken.session.SaSessionCustomUtil;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
|
||||
@RestController
|
||||
@@ -22,9 +22,16 @@ public class TestController {
|
||||
System.out.println("登录成功");
|
||||
System.out.println("当前是否登录:" + StpUtil.isLogin());
|
||||
System.out.println("当前登录账号:" + StpUtil.getLoginId());
|
||||
System.out.println("当前登录账号:" + StpUtil.getLoginId_asInt()); // 获取登录id并转为int
|
||||
|
||||
System.out.println("当前登录账号:" + StpUtil.getLoginId_asInt()); // 获取登录id并转为int
|
||||
|
||||
// StpUtil.logout();
|
||||
// System.out.println("注销登录");
|
||||
// System.out.println("当前是否登录:" + StpUtil.isLogin());
|
||||
// System.out.println("当前登录账号:" + StpUtil.getLoginId_defaultNull());
|
||||
// StpUtil.setLoginId(id); // 在当前会话登录此账号
|
||||
|
||||
System.out.println("当前token信息:" + StpUtil.getTokenInfo()); // 获取登录id并转为int
|
||||
System.out.println("当前登录账号:" + StpUtil.getLoginId_defaultNull());
|
||||
|
||||
return AjaxJson.getSuccess();
|
||||
}
|
||||
@@ -70,11 +77,11 @@ public class TestController {
|
||||
public AjaxJson session2() {
|
||||
System.out.println("======================= 进入方法,测试自定义session接口 ========================= ");
|
||||
// 自定义session就是无需登录也可以使用 的session :比如拿用户的手机号当做 key, 来获取 session
|
||||
System.out.println("自定义 session的id为:" + SaSessionUtil.getSessionById("1895544896").getId());
|
||||
System.out.println("测试取值name:" + SaSessionUtil.getSessionById("1895544896").getAttribute("name"));
|
||||
SaSessionUtil.getSessionById("1895544896").setAttribute("name", "张三"); // 写入值
|
||||
System.out.println("测试取值name:" + SaSessionUtil.getSessionById("1895544896").getAttribute("name"));
|
||||
System.out.println("测试取值name:" + SaSessionUtil.getSessionById("1895544896").getAttribute("name"));
|
||||
System.out.println("自定义 session的id为:" + SaSessionCustomUtil.getSessionById("1895544896").getId());
|
||||
System.out.println("测试取值name:" + SaSessionCustomUtil.getSessionById("1895544896").getAttribute("name"));
|
||||
SaSessionCustomUtil.getSessionById("1895544896").setAttribute("name", "张三"); // 写入值
|
||||
System.out.println("测试取值name:" + SaSessionCustomUtil.getSessionById("1895544896").getAttribute("name"));
|
||||
System.out.println("测试取值name:" + SaSessionCustomUtil.getSessionById("1895544896").getAttribute("name"));
|
||||
return AjaxJson.getSuccess();
|
||||
}
|
||||
|
||||
|
@@ -8,8 +8,8 @@ public class SaTokenConfig {
|
||||
private String tokenName = "satoken"; // token名称(同时也是cookie名称)
|
||||
private long timeout = 30 * 24 * 60 * 60; // token有效期,单位s 默认30天,-1为永不过期
|
||||
private Boolean isShare = true; // 在多人登录同一账号时,是否共享会话(为true时共用一个,为false时新登录挤掉旧登录)
|
||||
private Boolean isReadHead = false; // 是否在cookie读取不到token时,继续从请求header里继续尝试读取
|
||||
private Boolean isReadBody = false; // 是否在header读取不到token时,继续从请求题参数里继续尝试读取
|
||||
private Boolean isReadHead = true; // 是否在cookie读取不到token时,继续从请求header里继续尝试读取
|
||||
private Boolean isReadBody = true; // 是否在header读取不到token时,继续从请求题参数里继续尝试读取
|
||||
|
||||
private Boolean isV = true; // 是否在初始化配置时打印版本字符画
|
||||
|
||||
|
@@ -3,11 +3,11 @@ package cn.dev33.satoken.session;
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
|
||||
/**
|
||||
* sa-session工具类
|
||||
* 自定义sa-session工具类
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaSessionUtil {
|
||||
public class SaSessionCustomUtil {
|
||||
|
||||
// 添加上指定前缀,防止恶意伪造session
|
||||
public static String session_key = "custom";
|
0
sa-token-doc/doc/.nojekyll
Normal file
0
sa-token-doc/doc/.nojekyll
Normal file
49
sa-token-doc/doc/README.md
Normal file
49
sa-token-doc/doc/README.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# 介绍
|
||||
|
||||
------
|
||||
|
||||
## sa-token是什么?
|
||||
一个的`JavaWeb`权限认证框架,强大、简单、好用
|
||||
|
||||
> 与其它权限认证框架相比,sa-token尽力保证两点:
|
||||
> - 上手简单:能自动化的配置全部自动化,不让你费脑子
|
||||
> - 功能强大:能涵盖的功能全部涵盖,不让你用个框架还要自己给框架打各种补丁
|
||||
|
||||
|
||||
## 涵盖功能
|
||||
- 登录验证
|
||||
- 权限验证
|
||||
- 自定义session会话
|
||||
- 踢人下线
|
||||
- 模拟他人账号
|
||||
- 持久层扩展(集成redis)
|
||||
- 多账号认证体系(比如一个商城项目的user表和admin表)
|
||||
- 无cookie模式(APP、小程序等前后台分离场景)
|
||||
- 零配置与Spring等框架集成
|
||||
- ...
|
||||
|
||||
|
||||
## 贡献代码
|
||||
1. 在github上fork一份到自己的仓库
|
||||
2. clone自己的仓库到本地电脑
|
||||
3. 在本地电脑修改、commit、push
|
||||
4. 提交pr(点击:New Pull Request)(提交pr前请保证自己fork的仓库是最新版本,如若不是先强制更新一下)
|
||||
5. 等待合并
|
||||
|
||||
## 建议贡献的地方
|
||||
- 修复源码现有bug,或增加新的实用功能
|
||||
- 完善在线文档,或者修复现有错误之处
|
||||
- 更多demo示例:比如SSM版搭建步骤
|
||||
- 如果更新实用功能,可在文档友情链接处留下自己的推广链接
|
||||
|
||||
|
||||
## 交流群
|
||||
QQ交流群:[782974737 点击加入](https://jq.qq.com/?_wv=1027&k=5DHN5Ib) ,欢迎你的加入
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
31
sa-token-doc/doc/_sidebar.md
Normal file
31
sa-token-doc/doc/_sidebar.md
Normal file
@@ -0,0 +1,31 @@
|
||||
<!-- 这是目录树文件 -->
|
||||
|
||||
- **开始**
|
||||
- [介绍](/README)
|
||||
- [下载](/start/download)
|
||||
- [示例](/start/example)
|
||||
|
||||
- **使用**
|
||||
- [登录验证](/use/login-auth)
|
||||
- [权限验证](/use/jur-auth)
|
||||
- [session会话](/use/session)
|
||||
- [踢人下线](/use/kick)
|
||||
- [持久层扩展](/use/dao-extend)
|
||||
- [无cookie模式](/use/not-cookie)
|
||||
- [模拟他人](/use/mock-person)
|
||||
- [多账号验证](/use/many-account)
|
||||
- [框架配置](/use/config)
|
||||
|
||||
- **其它**
|
||||
- [常见问题](/more/common-questions)
|
||||
- [友情链接](/more/link)
|
||||
- [更新日志](/more/update-log)
|
||||
<!-- - [常见问题](/c1) -->
|
||||
<!-- - [常用函数](/c1) -->
|
||||
<!-- - [插件](/c1) -->
|
||||
<!-- - [关于](/c1) -->
|
||||
<!-- - eclipse插件 -->
|
||||
<!-- - idea插件 -->
|
||||
|
||||
|
||||
|
110
sa-token-doc/doc/index.html
Normal file
110
sa-token-doc/doc/index.html
Normal file
@@ -0,0 +1,110 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>sa-token</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="description" content="Description">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta name="keywords" content="sa-token|sa-token框架|sa-token文档|sa-token在线文档|权限认证框架">
|
||||
<meta name="description" content="sa-token是一个的JavaWeb权限认证框架,强大、简单、好用,登录验证、权限验证、自定义session会话、踢人下线、持久层扩展、无cookie模式、模拟他人账号、多账号体系、Spring集成...,零配置开箱即用,覆盖所有应用场景,你所需要的功能,这里都有">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="logo.png">
|
||||
<style type="text/css">
|
||||
.logo-box {
|
||||
position: absolute;
|
||||
left: 30px;
|
||||
top: 10px;
|
||||
cursor: pointer;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.logo-box img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.logo-box .logo-text {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
font-size: 24px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
#main {
|
||||
padding-bottom: 300px;
|
||||
}
|
||||
|
||||
#main h2 {
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
|
||||
#main h3 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
.logo-box {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a href="/">
|
||||
<div class="logo-box">
|
||||
<img src="logo.png" title="logo" />
|
||||
<h1 class="logo-text">sa-token</h1>
|
||||
</div>
|
||||
</a>
|
||||
<nav>
|
||||
<a href="/">首页</a>
|
||||
<a href="/doc/">文档</a>
|
||||
<a href="/doc/#/more/update-log">更新日志</a>
|
||||
</nav>
|
||||
<div id="app">加载中...</div>
|
||||
<script>
|
||||
var name = '<img style="width: 50px; height: 50px; vertical-align: middle;" src="logo.png" alt="logo" /> ';
|
||||
name += '<b style="font-size: 24px; vertical-align: middle;">sa-token</b> <sub>v1.0.0</sub>'
|
||||
// var name = '<b style="font-size: 24px; vertical-align: middle;">SqlFly</b> <sub>v1.0.0</sub>'
|
||||
window.$docsify = {
|
||||
name: name, // 名字
|
||||
repo: 'https://github.com/click33/sa-token', // github地址
|
||||
// themeColor: '#06A3D7', // 主题颜色
|
||||
// basePath: '/sa-token-doc/', // 设置文件加载的父路径, 这在一些带项目名部署的文件中非常有效
|
||||
// basePath: '/sa-token-doc/index.html',
|
||||
auto2top: true, // 是否在切换页面后回到顶部
|
||||
// coverpage: true, // 开启封面
|
||||
subMaxLevel: 3, // 标题解析层级, 写几就在目录树中解析到几级标题 ,一般写2吧也就
|
||||
loadSidebar: true, // 加载自定义侧边栏 , 目录定制在: _sidebar.md 文件 (需要创建 .nojekyll 的空文件,阻止 GitHub Pages 忽略命名是下划线开头的文件)
|
||||
copyCode: { // 复制插件
|
||||
buttonText: '复制到剪贴板',
|
||||
errorText: '错误',
|
||||
successText: '复制成功'
|
||||
},
|
||||
alias: {
|
||||
'/.*/_sidebar.md': '/_sidebar.md'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script src="https://unpkg.com/docsify@4.9.4/lib/docsify.min.js"></script>
|
||||
<script src="https://unpkg.com/docsify-copy-code@2.1.0/dist/docsify-copy-code.min.js"></script>
|
||||
<script src="https://unpkg.com/prismjs@1.19.0/components/prism-java.min.js"></script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var bp = document.createElement('script');
|
||||
var curProtocol = window.location.protocol.split(':')[0];
|
||||
if (curProtocol === 'https') {
|
||||
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
|
||||
} else {
|
||||
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
|
||||
}
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(bp, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
BIN
sa-token-doc/doc/logo.png
Normal file
BIN
sa-token-doc/doc/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
18
sa-token-doc/doc/more/common-questions.md
Normal file
18
sa-token-doc/doc/more/common-questions.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# 常见问题
|
||||
|
||||
---
|
||||
|
||||
### 用这个框架我需要很多配置吗?
|
||||
- 零配置开箱即用,但同时也支持自定义配置:参考:[框架配置](use/config)
|
||||
|
||||
### 如何踢人下线?
|
||||
- 参考:[踢人下线](use/kick)
|
||||
|
||||
### 能否集成redis?
|
||||
- 参考:[无cookie模式](use/dao-extend)
|
||||
|
||||
### 还是有不明白到的地方?
|
||||
- 请在`github`提交`issues`,或者加入qq群交流(群链接在[首页](README?id=交流群))
|
||||
|
||||
### 我能为这个框架贡献代码吗?
|
||||
- **可以**,请参照首页的提交pr步骤 ,[贡献代码](README?id=贡献代码)
|
9
sa-token-doc/doc/more/link.md
Normal file
9
sa-token-doc/doc/more/link.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# 友情链接
|
||||
|
||||
---
|
||||
|
||||
- **SqlFly:**[一个好用的ORM框架](https://sqlfly.dev33.cn/)
|
||||
- **sa-admin:**[一个基于多窗口后台模板, 强大、易用](http://sa-admin.dev33.cn/)
|
||||
- **颜值排行榜:**[一个以颜值为讨论主题的社区](http://web.yanzhi21.com/)
|
||||
- 虚位以待
|
||||
|
7
sa-token-doc/doc/more/update-log.md
Normal file
7
sa-token-doc/doc/more/update-log.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# 更新日志
|
||||
|
||||
|
||||
### 2020-2-4
|
||||
- 第一个版本出炉
|
||||
- GitHub:[https://github.com/click33/sa-token](https://github.com/click33/sa-token)
|
||||
- gitee:[https://gitee.com/sz6/sa-token](https://gitee.com/sz6/sa-token)
|
24
sa-token-doc/doc/start/download.md
Normal file
24
sa-token-doc/doc/start/download.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# 下载
|
||||
|
||||
------
|
||||
|
||||
|
||||
## 源码
|
||||
你可以通过`github`或者`gitee`来获取源码
|
||||
- github地址:[https://github.com/click33/sa-token](https://github.com/click33/sa-token)
|
||||
- gitee地址:[https://gitee.com/sz6/sa-token](https://gitee.com/sz6/sa-token)
|
||||
- 开源不易,求鼓励,给个star吧
|
||||
- 源码目录介绍
|
||||
- sa-token-dev: 源码
|
||||
- sa-token-demo-springboot: springboot集成示例
|
||||
- sa-token-doc: 文档介绍
|
||||
|
||||
|
||||
## jar包下载
|
||||
[点击下载](https://color-test.oss-cn-qingdao.aliyuncs.com/sa-token/sa-token-spring-1.0.0.jar)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
85
sa-token-doc/doc/start/example.md
Normal file
85
sa-token-doc/doc/start/example.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# 示例
|
||||
|
||||
---
|
||||
|
||||
> - 本篇将带你从零开始集成sa-token,从而让你快速熟悉sa-token的使用姿势
|
||||
> - 以maven + springboot为例
|
||||
|
||||
## springboot环境
|
||||
|
||||
#### 1、创建项目
|
||||
在IDE中新建一个Springboot项目,例如:`sa-token-demo-springboot`(不会的同学请自行百度或者参考github示例)
|
||||
|
||||
#### 2、设置jar包依赖
|
||||
- 在项目根目录新建文件夹`lib`,将 `sa-token-spring-xxx.jar` 复制到其中
|
||||
- 并在 `pom.xml` 中添加依赖:
|
||||
|
||||
``` xml
|
||||
<!-- sa-token 安全认证 -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33.sa-token</groupId>
|
||||
<artifactId>sa-token-spring</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/lib/sa-token-spring-1.0.0.jar</systemPath>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
#### 3、配置文件
|
||||
- 你可以零配置启动项目
|
||||
- 但同时你也可以在`application.yml`中增加如下配置,定制性使用框架:
|
||||
|
||||
``` java
|
||||
spring:
|
||||
# sa-token配置
|
||||
sa-token:
|
||||
# token名称(同时也是cookie名称)
|
||||
token-name: satoken
|
||||
# token有效期,单位s 默认30天,-1为永不过期
|
||||
timeout: 2592000
|
||||
# 在多人登录同一账号时,是否共享会话(为true时共用一个,为false时新登录挤掉旧登录)
|
||||
is-share: true
|
||||
# 是否在cookie读取不到token时,继续从请求header里继续尝试读取
|
||||
is-read-head: true
|
||||
# 是否在header读取不到token时,继续从请求题参数里继续尝试读取
|
||||
is-read-body: true
|
||||
# 是否在初始化配置时打印版本字符画
|
||||
is-v: true
|
||||
```
|
||||
|
||||
> - 如果你习惯于 `application.properties` 类型的配置文件,那也很好办:
|
||||
> - 百度: [springboot properties与yml 配置文件的区别](https://www.baidu.com/s?ie=UTF-8&wd=springboot%20properties%E4%B8%8Eyml%20%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E7%9A%84%E5%8C%BA%E5%88%AB)
|
||||
|
||||
#### 4、创建主类
|
||||
在项目中新建包 `com.pj` ,在此包内新建主类 `SaTokenDemoApplication.java`,输入以下代码:
|
||||
|
||||
``` java
|
||||
@SaTokenSetup // 标注启动 sa-token
|
||||
@SpringBootApplication
|
||||
public class SaTokenDemoApplication {
|
||||
public static void main(String[] args) throws JsonProcessingException {
|
||||
SpringApplication.run(SaTokenDemoApplication.class, args); // run-->
|
||||
System.out.println("启动成功:sa-token配置如下:" + SaTokenManager.getConfig());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 5、运行
|
||||
运行代码,当你从控制台看到类似下面的内容时,就代表框架已经成功集成了
|
||||
|
||||

|
||||
|
||||
|
||||
## 普通spring环境
|
||||
- 普通spring环境与springboot环境大体无异,只不过需要在项目根目录手动创建配置文件`sa-token.properties`来完成配置
|
||||
|
||||
|
||||
## 详细了解
|
||||
通过这个示例,你已经对sa-token有了初步的了解,那么现在开始详细了解一下它都有哪些[能力](/use/login-auth)吧
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
68
sa-token-doc/doc/use/config.md
Normal file
68
sa-token-doc/doc/use/config.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# 框架配置
|
||||
- 你可以零配置启动框架
|
||||
- 但同时你也可以通过配置,定制性使用框架,sa-token支持多种方式配置框架信息
|
||||
|
||||
---
|
||||
### 所有可配置项
|
||||
| 参数名称 | 类型 | 默认值 | 说明 |
|
||||
| :-------- | :-------- | :-------- | :-------- |
|
||||
| tokenName | String | satoken | token名称(同时也是cookie名称) |
|
||||
| timeout | long | 2592000 | token有效期,单位s 默认30天,-1为永不过期 |
|
||||
| isShare | Boolean | true | 在多人登录同一账号时,是否共享会话(为true时共用一个,为false时新登录挤掉旧登录) |
|
||||
| isReadHead| Boolean | true | 是否在cookie读取不到token时,继续从请求header里继续尝试读取 |
|
||||
| isReadBody| Boolean | true | 是否在header读取不到token时,继续从请求题参数里继续尝试读取 |
|
||||
| isV | Boolean | true | 是否在初始化配置时打印版本字符画 |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 方式1、通过代码配置
|
||||
``` java
|
||||
/**
|
||||
* sa-token代码方式进行配置
|
||||
*/
|
||||
@Configuration
|
||||
public class MySaTokenConfig {
|
||||
|
||||
// 获取配置Bean
|
||||
@Primary
|
||||
@Bean(name="MySaTokenConfig")
|
||||
public SaTokenConfig getSaTokenConfig() {
|
||||
SaTokenConfig config = new SaTokenConfig();
|
||||
config.setTokenName("satoken"); // token名称(同时也是cookie名称)
|
||||
config.setTimeout(30 * 24 * 60 * 60); // token有效期,单位s 默认30天,-1为永不过期
|
||||
config.setIsShare(true); // 在多人登录同一账号时,是否共享会话(为true时共用一个,为false时新登录挤掉旧登录)
|
||||
config.setIsReadHead(true); // 是否在cookie读取不到token时,继续从请求header里继续尝试读取
|
||||
config.setIsReadBody(true); // 是否在cookie读取不到token时,继续从请求header里继续尝试读取
|
||||
config.setIsV(true); // 是否在初始化配置时打印版本字符画
|
||||
return config;
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### 方式2、在`application.yml`配置
|
||||
|
||||
``` java
|
||||
spring:
|
||||
# sa-token配置
|
||||
sa-token:
|
||||
# token名称(同时也是cookie名称)
|
||||
token-name: satoken
|
||||
# token有效期,单位s 默认30天,-1为永不过期
|
||||
timeout: 2592000
|
||||
# 在多人登录同一账号时,是否共享会话(为true时共用一个,为false时新登录挤掉旧登录)
|
||||
is-share: true
|
||||
# 是否在cookie读取不到token时,继续从请求header里继续尝试读取
|
||||
is-read-head: true
|
||||
# 是否在header读取不到token时,继续从请求题参数里继续尝试读取
|
||||
is-read-body: true
|
||||
# 是否在初始化配置时打印版本字符画
|
||||
is-v: true
|
||||
```
|
||||
|
||||
- 如果你习惯于 `application.properties` 类型的配置文件,那也很好办:
|
||||
- 百度: [springboot properties与yml 配置文件的区别](https://www.baidu.com/s?ie=UTF-8&wd=springboot%20properties%E4%B8%8Eyml%20%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E7%9A%84%E5%8C%BA%E5%88%AB)
|
||||
|
||||
|
106
sa-token-doc/doc/use/dao-extend.md
Normal file
106
sa-token-doc/doc/use/dao-extend.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# 持久层扩展
|
||||
---
|
||||
- 每次重启项目就得重新登录一遍,我想把登录数据都放在redis里,这样重启项目也不用重新登录,行不行?
|
||||
- 行!
|
||||
- 你需要做的就是重写`sa-token`的dao层实现方式,参考以下方案:
|
||||
|
||||
|
||||
## 具体代码
|
||||
- 新建文件`SaTokenDaoRedis.java`,实现接口`SaTokenDao`, 并加上注解`@Component`,保证此类被springboot扫描到
|
||||
- 代码参考:
|
||||
|
||||
```java
|
||||
|
||||
package com.pj.satoken;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
// import org.springframework.stereotype.Component;
|
||||
|
||||
import cn.dev33.satoken.dao.SaTokenDao;
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
|
||||
/**
|
||||
* sa-token持久层的实现类 , 基于redis
|
||||
*/
|
||||
@Component // 保证此类被springboot扫描,即可完成sa-token与redis的集成
|
||||
public class SaTokenDaoRedis implements SaTokenDao {
|
||||
|
||||
|
||||
// string专用
|
||||
@Autowired
|
||||
StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
// SaSession专用
|
||||
RedisTemplate<String, SaSession> redisTemplate;
|
||||
@Autowired
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public void setRedisTemplate(RedisTemplate redisTemplate) {
|
||||
RedisSerializer stringSerializer = new StringRedisSerializer();
|
||||
redisTemplate.setKeySerializer(stringSerializer);
|
||||
this.redisTemplate = redisTemplate;
|
||||
}
|
||||
|
||||
|
||||
// 根据key获取value ,如果没有,则返回空
|
||||
@Override
|
||||
public String getValue(String key) {
|
||||
return stringRedisTemplate.opsForValue().get(key);
|
||||
}
|
||||
|
||||
// 写入指定key-value键值对,并设定过期时间(单位:秒)
|
||||
@Override
|
||||
public void setValue(String key, String value, long timeout) {
|
||||
stringRedisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
// 删除一个指定的key
|
||||
@Override
|
||||
public void delKey(String key) {
|
||||
stringRedisTemplate.delete(key);
|
||||
}
|
||||
|
||||
|
||||
// 根据指定key的session,如果没有,则返回空
|
||||
@Override
|
||||
public SaSession getSaSession(String sessionId) {
|
||||
return redisTemplate.opsForValue().get(sessionId);
|
||||
}
|
||||
|
||||
// 将指定session持久化
|
||||
@Override
|
||||
public void saveSaSession(SaSession session, long timeout) {
|
||||
redisTemplate.opsForValue().set(session.getId(), session, timeout, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
// 更新指定session
|
||||
@Override
|
||||
public void updateSaSession(SaSession session) {
|
||||
long expire = redisTemplate.getExpire(session.getId());
|
||||
if(expire == -2) { // -2 = 无此键
|
||||
return;
|
||||
}
|
||||
redisTemplate.opsForValue().set(session.getId(), session, expire, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
// 删除一个指定的session
|
||||
@Override
|
||||
public void delSaSession(String sessionId) {
|
||||
redisTemplate.delete(sessionId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
- 可参考代码:[码云:SaTokenDaoRedis.java](https://gitee.com/sz6/sa-token/blob/master/sa-token-demo-springboot/src/main/java/com/pj/satoken/SaTokenDaoRedis.java)
|
||||
|
75
sa-token-doc/doc/use/jur-auth.md
Normal file
75
sa-token-doc/doc/use/jur-auth.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# 权限验证
|
||||
---
|
||||
|
||||
|
||||
## 核心思想
|
||||
|
||||
- 所谓权限验证,验证的核心就是当前账号是否拥有一个权限码
|
||||
- 有:就让你通过、没有:那么禁止访问
|
||||
- 再往底了说,就是每个账号都会拥有一个权限码集合,我来验证这个集合中是否包括我需要检测的那个权限码
|
||||
- 例如:当前账号拥有权限码集合:`[101, 102, "user-add", "user-get"]`,这时候我去验证权限码:`201`,则结果就是验证失败,禁止访问
|
||||
- 所以现在问题的核心就是,1、如何获取一个账号所拥有的的权限码集合,2、本次操作要验证的权限码是哪个
|
||||
|
||||
## 获取当前账号权限码集合
|
||||
因为每个项目的需求不同,其权限设计也千变万化,所以【获取当前账号权限码集合】这一操作不可能内置到框架中,
|
||||
所以`sa-token`将此操作以接口的方式暴露给你,以方便的你根据自己的业务逻辑进行重写
|
||||
|
||||
- 你需要做的就是新建一个类,重写`StpInterface`接口,例如以下代码:
|
||||
|
||||
``` java
|
||||
package com.pj.satoken;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.springframework.stereotype.Component;
|
||||
import cn.dev33.satoken.stp.StpInterface;
|
||||
|
||||
/**
|
||||
* 自定义权限验证接口扩展
|
||||
*/
|
||||
@Component // 保证此类被springboot扫描,完成sa-token的自定义权限验证扩展
|
||||
public class StpCustom implements StpInterface {
|
||||
|
||||
// 返回一个账号所拥有的权限码集合
|
||||
@Override
|
||||
public List<Object> getPermissionCodeList(Object login_id, String login_key) {
|
||||
List<Object> list = new ArrayList<Object>(); // 本list仅做模拟,实际项目中要根据具体业务逻辑来查询权限
|
||||
list.add("101");
|
||||
list.add("user-add");
|
||||
list.add("user-delete");
|
||||
list.add("user-update");
|
||||
list.add("user-get");
|
||||
list.add("article-get");
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
- 可参考代码:[码云:StpCustom.java](https://gitee.com/sz6/sa-token/blob/master/sa-token-demo-springboot/src/main/java/com/pj/satoken/StpCustom.java)
|
||||
|
||||
|
||||
|
||||
## 验证是否包含指定权限码
|
||||
然后就可以用以下api来鉴权了
|
||||
|
||||
#### StpUtil.hasPermission(Object pcode)
|
||||
- 查询当前账号是否含有指定权限,返回true或false
|
||||
|
||||
#### StpUtil.checkPermission(Object pcode)
|
||||
- 检测当前账号是否含有指定权限,如果有则安全通过,如果没有则抛出异常:`NotPermissionException`
|
||||
|
||||
#### StpUtil.checkPermissionAnd(Object... pcode)
|
||||
- 检测当前账号是否含有指定权限【指定多个,必须全都有,否则抛出异常】
|
||||
|
||||
#### StpUtil.checkPermissionOr(Object... pcode)
|
||||
- 检测当前账号是否含有指定权限【指定多个,有一个就可以了,全都没有才会抛出异常】
|
||||
|
||||
|
||||
|
||||
|
||||
## 拦截全局异常
|
||||
- 有同学要问,鉴权失败,抛出异常,然后呢?要把异常显示给用户看吗?
|
||||
- 当然不能把异常抛给用户看,你可以创建一个全局异常拦截器,统一返回给前端的格式,例如以下示例:
|
||||
- 参考:[码云:TopController.java](https://gitee.com/sz6/sa-token/blob/master/sa-token-demo-springboot/src/main/java/com/pj/test/TopController.java)
|
15
sa-token-doc/doc/use/kick.md
Normal file
15
sa-token-doc/doc/use/kick.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# 踢人下线
|
||||
---
|
||||
|
||||
|
||||
## 核心思想
|
||||
|
||||
- 所谓踢人下线,核心操作就是找到其指定login_id的token,并设置其失效
|
||||
|
||||
|
||||
## 具体API
|
||||
|
||||
#### StpUtil.logoutByLoginId(Object login_id)
|
||||
- 让指定login_id的会话注销登录(踢人下线)
|
||||
|
||||
|
38
sa-token-doc/doc/use/login-auth.md
Normal file
38
sa-token-doc/doc/use/login-auth.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# 登录验证
|
||||
---
|
||||
|
||||
|
||||
## 核心思想
|
||||
|
||||
- 所谓登录验证,说白了就是限制某些接口只有登录后才能访问(如:查询我的账号资料)
|
||||
- 如何判断你有没有登录?当然是登录成功后我给你做个标记
|
||||
- 在需要鉴权的接口里检查标记,有标记者视为已登录,无标记者视为未登录
|
||||
- 根据以上思路,我们很容易想到以下api:
|
||||
|
||||
|
||||
## 具体API
|
||||
|
||||
#### StpUtil.setLoginId(Object login_id)
|
||||
- 标记当前会话登录的账号id
|
||||
- 建议的参数类型:long | int | String, 不可以传入复杂类型,如:User、Admin等等
|
||||
|
||||
#### StpUtil.logout()
|
||||
- 当前会话注销登录
|
||||
|
||||
#### StpUtil.isLogin()
|
||||
- 获取当前会话是否已经登录,返回true=已登录,false=未登录
|
||||
|
||||
#### StpUtil.getLoginId()
|
||||
- 获取当前会话登录id, 如果未登录,则抛出异常:`NotLoginException`
|
||||
- 类似API还有:
|
||||
- `StpUtil.getLoginId_asString()` 获取当前会话登录id, 并转化为String类型
|
||||
- `StpUtil.getLoginId_asInt()` 获取当前会话登录id, 并转化为int类型
|
||||
- `StpUtil.getLoginId_asLong()` 获取当前会话登录id, 并转化为long类型
|
||||
|
||||
#### StpUtil.getLoginId(T default_value)
|
||||
- 获取当前会话登录id, 如果未登录,则返回默认值 (default_value可以为任意类型)
|
||||
- 类似API还有:
|
||||
- `StpUtil.getLoginId_defaultNull()` 获取当前会话登录id, 如果未登录,则返回null
|
||||
|
||||
|
||||
|
28
sa-token-doc/doc/use/many-account.md
Normal file
28
sa-token-doc/doc/use/many-account.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# 多账号验证
|
||||
---
|
||||
|
||||
## 问题
|
||||
- 有的时候在一个项目中,我们会设计两套账号体系,比如一个商城的user表和admin表
|
||||
- 这时候,我们就需要将两套账号的权限认证分开,防止冲突
|
||||
|
||||
|
||||
## 核心思想
|
||||
- sa-token在设计时充分考虑了多账号体系时的各种逻辑
|
||||
- 以上几篇介绍的api,都是经过 `StpUtil`类的各种静态方法进行各种验证,而如果你深入它的源码,[点此阅览](https://gitee.com/sz6/sa-token/blob/master/sa-token-dev/src/main/java/cn/dev33/satoken/stp/StpUtil.java)
|
||||
- 就会发现,此类并没有任何代码逻辑,唯一做的事就是对成员变量`stpLogic`的各个API进行包装一下进行转发
|
||||
- 这样做有两个优点
|
||||
- `StpLogic`类的所有函数都可以被重写,按需扩展
|
||||
- 在构造方法时随意传入一个不同的 `login_key`,就可以再造一套账号登录体系
|
||||
|
||||
## 操作示例
|
||||
1. 新建一个新的权限验证类,比如: `StpAdminUtil.java`
|
||||
2. 将`StpUtil.java`类的全部代码复制粘贴到 `StpAdminUtil.java`里
|
||||
3. 更改一下其 `login_key`, 比如:
|
||||
```
|
||||
// 底层的 StpLogic 对象
|
||||
public static StpLogic stpLogic = new StpLogic("admin"); // login_key改为admin
|
||||
```
|
||||
4. 接下来就可以像调用`StpUtil.java`一样调用 `StpAdminUtil.java`了,这两套账号认证的逻辑是完全隔离的
|
||||
|
||||
|
||||
|
24
sa-token-doc/doc/use/mock-person.md
Normal file
24
sa-token-doc/doc/use/mock-person.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# 模拟他人
|
||||
---
|
||||
|
||||
- 以上介绍的api都是操作当前账号,对当前账号进行各种鉴权操作,你可能会问,我能不能对别的账号进行一些操作?
|
||||
- 比如:查看账号10001有无某个权限码、获取id账号为10002的用户session,等等...
|
||||
- `sa-token`在api设计时充分考虑了这一点,暴露出多个api进行此类操作
|
||||
|
||||
|
||||
## 有关操作其它账号的api
|
||||
|
||||
#### StpUtil.getTokenValueByLoginId(Object login_id)
|
||||
- 获取指定login_id的tokenValue值
|
||||
|
||||
#### StpUtil.logoutByLoginId(Object login_id)
|
||||
- 指定login_id的会话注销登录(踢人下线)
|
||||
|
||||
#### StpUtil.getSessionByLoginId(Object login_id)
|
||||
- 获取指定login_id的session
|
||||
|
||||
#### StpUtil.hasPermission(Object login_id, Object pcode)
|
||||
- 指定login_id是否含有指定权限
|
||||
|
||||
|
||||
|
47
sa-token-doc/doc/use/not-cookie.md
Normal file
47
sa-token-doc/doc/use/not-cookie.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# 无cookie模式
|
||||
---
|
||||
|
||||
## 何为无cookie
|
||||
|
||||
- 常规PC端鉴权方法,一般由cookie进行
|
||||
- 而cookie有两个特性:1、可由后端控制写入,2、每次请求自动提交
|
||||
- 这就使得大多数web前端码农,无需任何特殊操作,就能完成鉴权的流程(因为整个流程都是后端控制完成的)
|
||||
- 而在app、小程序等前后台分离场景中,是没有cookie这一功能的,此时大多数人都会一脸懵逼,咋进行鉴权啊
|
||||
- 其实很简单
|
||||
- 不能后端控制写入了,就前端自己写入(难点在**如何将token传递到前端**)
|
||||
- 每次请求不能自动提交了,那就手动提交(难点在前端如何**将token传递到后端**,同时后端**将其读取出来**)
|
||||
|
||||
|
||||
## 将token传递到前端
|
||||
|
||||
1. 首先调用 `StpUtil.setLoginId(Object login_id)` 进行登录
|
||||
2. 调用 `StpUtil.getTokenInfo()` 返回当前会话的token值
|
||||
- 此方法返回一个Map,有两个key:tokenName和tokenValue(token的名称和token的值)
|
||||
- 将此Map传递到前台,让前端人员将这两个值保存到本地
|
||||
|
||||
## 前端将token提交到后端
|
||||
1. 无论是app还是小程序,其传递方式都大同小异
|
||||
2. 那就是,将token塞到请求header里 ,格式为:`{tokenName: tokenValue}`
|
||||
3. 以经典跨端框架`uni-app`为例:
|
||||
```
|
||||
var tokenName = uni.getStorageSync('tokenName'); // 从本地缓存读取tokenName值
|
||||
var tokenValue = uni.getStorageSync('tokenValue'); // 从本地缓存读取tokenValue值
|
||||
var header = {
|
||||
"content-type": "application/x-www-form-urlencoded" // 防止后台拿不到参数
|
||||
};
|
||||
if (tokenName != undefined && tokenName != '') {
|
||||
header[tokenName] = tokenValue;
|
||||
}
|
||||
// 后续在发起请求时将 header 对象塞到请求头部
|
||||
```
|
||||
|
||||
4. 只要按照如此方法将token值传递到后端,`sa-token`就能像传统PC端一样自动读取到token值,进行鉴权
|
||||
5. 你可能会有疑问,难道我每个ajax都要写这么一坨?岂不是麻烦死了
|
||||
- 你当然不能每个ajax都写这么一坨,因为这种重复代码都是要封装在一个函数里统一调用的
|
||||
|
||||
|
||||
## 其它解决方案?
|
||||
- 如果你对cookie非常了解,那你就会明白,所谓cookie,本质上就是一个特殊的header参数而已,
|
||||
- 而既然它只是一个header参数,我们就能就能手动模拟实现它,从而完成鉴权操作
|
||||
- 这其实是对无cookie模式的另一种解决方案,有兴趣的同学可以百度了解一下,在此暂不赘述
|
||||
|
37
sa-token-doc/doc/use/session.md
Normal file
37
sa-token-doc/doc/use/session.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# session会话
|
||||
---
|
||||
|
||||
|
||||
## 账号session
|
||||
账号session指的是为每个登录账号分配的session
|
||||
|
||||
#### StpUtil.getSession()
|
||||
- 返回当前登录账号的session(必须是登录后才能调用)
|
||||
|
||||
|
||||
## 自定义session
|
||||
自定义session指的是未登录状态下,以一个特定的值作为key,来分配的session
|
||||
|
||||
#### SaSessionCustomUtil.isExists(String sessionId)
|
||||
- 查询指定key的session,是否存在
|
||||
|
||||
#### SaSessionCustomUtil.getSessionById(String sessionId)
|
||||
- 获取指定key的session,如果没有,则新建并返回
|
||||
|
||||
#### SaSessionCustomUtil.delSessionById(String sessionId)
|
||||
- 删除指定key的session
|
||||
|
||||
|
||||
## session相关操作
|
||||
那么获取到的`SaSession`具体有哪些方法可供操作?
|
||||
|
||||
#### getId()
|
||||
- 返回此session的id
|
||||
|
||||
#### setAttribute(String key, Object value)
|
||||
- 在此session对象上写入值
|
||||
|
||||
#### getAttribute(String key)
|
||||
- 在此session对象上查询值
|
||||
|
||||
具体可参考`javax.servlet.http.HttpSession`,`SaSession`所含方法与其大体类似
|
60
sa-token-doc/index.css
Normal file
60
sa-token-doc/index.css
Normal file
@@ -0,0 +1,60 @@
|
||||
/* ================================== 内容 ====================================== */
|
||||
/* 总 */
|
||||
*{margin: 0px; padding: 0px;}
|
||||
body{font-size: 16px; color: #34495E; font-family: "Source Sans Pro","Helvetica Neue","Arial,sans-serif";}
|
||||
header{height: 70px; border: 0px #000 solid; position: fixed; width: 100%;}
|
||||
/* logo部分 */
|
||||
.logo-box {margin-top: 15px; margin-left: 30px; cursor: pointer; color: #000; float: left;}
|
||||
.logo-box img {width: 50px; height: 50px; vertical-align: middle;}
|
||||
.logo-box .logo-text {display: inline-block;vertical-align: middle; font-size: 22px;font-weight: 400;}
|
||||
/* 右边导航 */
|
||||
.nav-right{float: right; line-height: 70px; padding-right: 4.5em;}
|
||||
.nav-right a{padding: 0px 1em; color: #34495E; text-decoration: none; transition: all 0.2s;}
|
||||
.nav-right a:hover{color: #42B983;}
|
||||
/* 主要 */
|
||||
html,body,.main-box{width: 100%; height: 100%; }
|
||||
.main-box{display: flex; align-items: center; text-align: center;}
|
||||
.main-box .content-box{flex: 1;}
|
||||
|
||||
.content-box h1{font-size: 110px; font-weight: 300; position: relative;}
|
||||
.content-box h1 small{font-size: 20px; position: absolute; bottom: 0px;}
|
||||
.sub-title{font-size: 24px; font-weight: 400; margin-top: 30px; margin-bottom: 25px;}
|
||||
.content-box p{line-height: 30px;}
|
||||
|
||||
.btn-box{margin-top: 16px;}
|
||||
.btn-box a{
|
||||
border: 1px #42B983 solid;
|
||||
border-radius: 2rem;
|
||||
box-sizing: border-box;
|
||||
color: #42B983;
|
||||
display: inline-block;
|
||||
font-size: 1.05rem;
|
||||
letter-spacing: .1rem;
|
||||
margin: .5rem 1rem;
|
||||
padding: 0.9em 2rem;
|
||||
text-decoration: none;
|
||||
transition: all .15s ease;
|
||||
}
|
||||
/* 最后一个 */
|
||||
.btn-box a:last-child {
|
||||
background-color: #42B983;
|
||||
color: #fff;
|
||||
}
|
||||
.btn-box a:hover{color: #000;}
|
||||
|
||||
/* 底部 */
|
||||
footer{
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
line-height: 80px;
|
||||
text-align: center;
|
||||
}
|
||||
footer a{color: inherit; text-decoration: none;}
|
||||
footer a:hover{text-decoration: underline;}
|
||||
|
||||
/* 媒体查询 */
|
||||
@media screen and (max-width: 800px) {
|
||||
.logo-box,.copyright {display: none;}
|
||||
}
|
||||
|
@@ -1,11 +1,96 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>sa-token在线文档</title>
|
||||
<meta charset="UTF-8">
|
||||
<title>sa-token</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="description" content="Description">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta name="keywords" content="sa-token|sa-token框架|sa-token文档|sa-token在线文档|权限认证框架">
|
||||
<meta name="description" content="sa-token是一个的JavaWeb权限认证框架,强大、简单、好用,登录验证、权限验证、自定义session会话、踢人下线、持久层扩展、无cookie模式、模拟他人账号、多账号体系、Spring集成...,零配置开箱即用,覆盖所有应用场景,你所需要的功能,这里都有">
|
||||
<link rel="stylesheet" href="https://unpkg.com/docsify/lib/themes/vue.css">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="doc/logo.png">
|
||||
<link rel="stylesheet" href="index.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<h1>sa-token在线文档</h1>
|
||||
<header>
|
||||
<a href="/" style="text-decoration: none;">
|
||||
<div class="logo-box">
|
||||
<img src="doc/logo.png" title="logo">
|
||||
<span class="logo-text">sa-token</span>
|
||||
</div>
|
||||
</a>
|
||||
<nav class="nav-right">
|
||||
<a href="/">首页</a>
|
||||
<a href="/doc/">文档</a>
|
||||
<a href="/doc/#/more/update-log">更新日志</a>
|
||||
<!-- github小猫图标 -->
|
||||
<a href="https://github.com/click33/sa-token" class="github-corner" aria-label="View source on Github" style="position: fixed; right: -16px;">
|
||||
<svg viewBox="0 0 250 250" aria-hidden="true">
|
||||
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
|
||||
<path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
|
||||
fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
|
||||
<path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
|
||||
fill="currentColor" class="octo-body"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<!-- 内容部分 -->
|
||||
<div class="main-box">
|
||||
<div class="content-box">
|
||||
<h1>sa-token<small>v1.0.0</small></h1>
|
||||
<div class="sub-title">一个的JavaWeb权限认证框架,强大、简单、好用</div>
|
||||
<!-- <p>0配置开箱即用,低学习成本</p> -->
|
||||
<p>登录验证、权限验证、自定义session会话、踢人下线、持久层扩展、无cookie模式、模拟他人账号、多账号体系、Spring集成...</p>
|
||||
<p>零配置开箱即用,覆盖所有应用场景,你所需要的功能,这里都有</p>
|
||||
<div class="btn-box">
|
||||
<a href="https://github.com/click33/sa-token" target="_blank">GitHub</a>
|
||||
<a href="https://gitee.com/sz6/sa-token" target="_blank">码云</a>
|
||||
<a href="doc/" target="_self">开发文档</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<p>
|
||||
<span class="copyright">Copyright © 2020 </span>
|
||||
<a href="http://www.miitbeian.gov.cn/" target="_blank">鲁ICP备18046274号-2</a>
|
||||
QQ交流群:<a href="https://jq.qq.com/?_wv=1027&k=5DHN5Ib" target="_blank">784013340</a>
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
// 随机数
|
||||
function randomNum(minNum, maxNum) {
|
||||
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10)
|
||||
}
|
||||
// 随机一个渐变背景色
|
||||
function randomBG() {
|
||||
var c1 = randomNum(0, 255);
|
||||
var c2 = randomNum(0, 255);
|
||||
document.body.style.background = 'linear-gradient(to left bottom, hsl(' + c1 + ', 100%, 85%) 0%,hsl(' + c2 +
|
||||
', 100%, 85%) 100%)';
|
||||
}
|
||||
randomBG();
|
||||
</script>
|
||||
|
||||
<!-- 自动提交 -->
|
||||
<script>
|
||||
(function() {
|
||||
var bp = document.createElement('script');
|
||||
var curProtocol = window.location.protocol.split(':')[0];
|
||||
if (curProtocol === 'https') {
|
||||
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
|
||||
} else {
|
||||
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
|
||||
}
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(bp, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
Reference in New Issue
Block a user