mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-04-05 17:37:53 +08:00
sa-token-quick-login 模块完毕
This commit is contained in:
parent
ca2599c528
commit
0a7a8138b3
1
pom.xml
1
pom.xml
@ -21,6 +21,7 @@
|
||||
<module>sa-token-core</module>
|
||||
<module>sa-token-starter</module>
|
||||
<module>sa-token-plugin</module>
|
||||
<!-- <module>sa-token-demo\sa-token-demo-quick-login</module> -->
|
||||
</modules>
|
||||
|
||||
<!-- 开源协议 apache 2.0 -->
|
||||
|
68
sa-token-demo/sa-token-demo-quick-login/pom.xml
Normal file
68
sa-token-demo/sa-token-demo-quick-login/pom.xml
Normal file
@ -0,0 +1,68 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-demo-quick-login</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<!-- SpringBoot -->
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.0.0.RELEASE</version>
|
||||
</parent>
|
||||
|
||||
<!-- 定义sa-token版本号 -->
|
||||
<properties>
|
||||
<sa-token-version>1.18.0</sa-token-version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- springboot依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-starter</artifactId>
|
||||
<version>${sa-token-version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- quick-login -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-quick-login</artifactId>
|
||||
<version>${sa-token-version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- @ConfigurationProperties -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- 热更新插件 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,52 @@
|
||||
package com.pj;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import cn.dev33.satoken.quick.SaQuickManager;
|
||||
|
||||
/**
|
||||
* springboot启动之后
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class SaQuicikStartup implements CommandLineRunner {
|
||||
|
||||
@Value("${spring.application.name:sa-quick}")
|
||||
private String applicationName;
|
||||
|
||||
@Value("${server.port:8080}")
|
||||
private String port;
|
||||
|
||||
@Value("${server.servlet.context-path:}")
|
||||
private String path;
|
||||
|
||||
// @Value("${spring.profiles.active:}")
|
||||
// private String active;
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
String str = "\n------------- " + applicationName + " 启动成功 (" + getNow() + ") -------------\n" +
|
||||
" - home: " + "http://localhost:" + port + path + "\n" +
|
||||
" - name: " + SaQuickManager.getConfig().getName() + "\n"+
|
||||
" - pwd : " + SaQuickManager.getConfig().getPwd() + "\n";
|
||||
System.out.println(str);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 返回系统当前时间的YYYY-MM-dd hh:mm:ss 字符串格式
|
||||
*/
|
||||
private static String getNow(){
|
||||
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,15 @@
|
||||
package com.pj;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@SpringBootApplication
|
||||
@Configuration
|
||||
public class SaTokenQuickDemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SaTokenQuickDemoApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.pj.test;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import cn.dev33.satoken.util.SaTokenConsts;
|
||||
|
||||
/**
|
||||
* 测试专用Controller
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
public class TestController {
|
||||
|
||||
// 浏览器访问测试: http://localhost:8081
|
||||
@RequestMapping({"/"})
|
||||
public String login(String username, String password) {
|
||||
String str = "<br />"
|
||||
// + "<h1 style='text-align: center;'>Welcome to the system</h1>"
|
||||
+ "<h1 style='text-align: center;'>资源页 (登录后才可进入本页面) </h1>"
|
||||
+ "<hr/>"
|
||||
+ "<p style='text-align: center;'> Sa-Token " + SaTokenConsts.VERSION_NO + " </p>";
|
||||
return str;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
# 端口
|
||||
server:
|
||||
port: 8081
|
||||
|
||||
# Sa-Token-Quick-Login 配置
|
||||
sa:
|
||||
# 登录账号
|
||||
name: sa
|
||||
# 登录密码
|
||||
pwd: 123456
|
||||
# 是否自动随机生成账号密码 (此项为true时, name与pwd失效)
|
||||
auto: false
|
||||
# 是否开启全局认证(关闭后将不再强行拦截)
|
||||
auth: true
|
||||
# 登录页标题
|
||||
title: Sa-Token 登录
|
||||
# 是否显示底部版权信息
|
||||
copr: true
|
||||
# 将本地磁盘的某个路径作为静态资源开放
|
||||
# dir: file:E:\static
|
||||
|
||||
|
||||
# 静态文件路径映射
|
||||
spring:
|
||||
resources:
|
||||
static-locations: classpath:/META-INF/resources/,classpath:/resources/, classpath:/static/, classpath:/public/, ${sa.dir:}
|
||||
|
@ -34,7 +34,7 @@ public class SaTokenConfigure implements WebMvcConfigurer {
|
||||
* 注册 [sa-token全局过滤器]
|
||||
*/
|
||||
@Bean
|
||||
public SaServletFilter getSaReactorFilter() {
|
||||
public SaServletFilter getSaServletFilter() {
|
||||
return new SaServletFilter()
|
||||
|
||||
// 指定 [拦截路由] 与 [放行路由]
|
||||
|
@ -44,11 +44,6 @@ spring:
|
||||
min-idle: 0
|
||||
|
||||
|
||||
|
||||
# 静态文件路径映射
|
||||
resources:
|
||||
static-locations: file:E:\work\project-yun\sa-admin
|
||||
|
||||
|
||||
|
||||
|
@ -33,6 +33,10 @@
|
||||
- [单点登录](/senior/sso)
|
||||
- [多账号验证](/use/many-account)
|
||||
|
||||
- **插件**
|
||||
- [AOP注解鉴权](/plugin/aop-at)
|
||||
- [Quick-Login快速登录插件](/plugin/quick-login)
|
||||
|
||||
- **其它**
|
||||
- [常见问题](/more/common-questions)
|
||||
- [更新日志](/more/update-log)
|
||||
|
30
sa-token-doc/doc/plugin/aop-at.md
Normal file
30
sa-token-doc/doc/plugin/aop-at.md
Normal file
@ -0,0 +1,30 @@
|
||||
# AOP注解鉴权
|
||||
---
|
||||
|
||||
在 [注解式鉴权](/use/at-check) 章节,我们非常轻松的实现了注解鉴权,
|
||||
但是默认的拦截器模式却有一个缺点,那就是无法在`Controller层`以外的代码使用进行校验
|
||||
|
||||
因此Sa-Token提供AOP插件,你只需在`pom.xml`里添加如下依赖,便可以在任意层级使用注解鉴权
|
||||
|
||||
``` xml
|
||||
<!-- sa-token整合SpringAOP实现注解鉴权 -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-aop</artifactId>
|
||||
<version>1.18.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
|
||||
#### 注意点:
|
||||
- 使用拦截器模式,只能把注解写在`Controller层`,使用AOP模式,可以将注解写在任意层级 <br>
|
||||
- **拦截器模式和AOP模式不可同时集成**,否则会在`Controller层`发生一个注解校验两次的bug
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
232
sa-token-doc/doc/plugin/quick-login.md
Normal file
232
sa-token-doc/doc/plugin/quick-login.md
Normal file
@ -0,0 +1,232 @@
|
||||
# Sa-Token-Quick-Login 快速登录认证
|
||||
---
|
||||
|
||||
|
||||
### 解决什么问题
|
||||
|
||||
Sa-Token-Quick-Login 可以为一个系统快速的、零代码 注入一个登录页面
|
||||
|
||||
试想一下,假如我们开发了一个非常简单的小系统,比如说:服务器性能监控页面,
|
||||
我们将它部署在服务器上,通过访问这个页面,我们可以随时了解服务器性能信息,非常方便
|
||||
|
||||
然而,这个页面方便我们的同时,也方便了一些不法的攻击者,由于这个页面毫无防护的暴露在公网中,任何一台安装了浏览器的电脑都可以随时访问它!
|
||||
|
||||
为此,我们必须给这个系统加上一个登录认证,只有知晓了后台密码的人员才可以进行访问
|
||||
|
||||
细细想来,完成这个功能你需要:
|
||||
|
||||
1. 编写前端登录页面,手写各种表单样式
|
||||
2. 寻找合适的ajax类库,`jQuery`?`Axios`?还是直接前后台不分离?
|
||||
3. 寻找合适的模板引擎,比如`jsp`、`Thymeleaf`、`FreeMarker`、`Velocity`……选哪个呢?
|
||||
4. 处理后台各种拦截认证逻辑,前后台接口对接
|
||||
5. 你可能还会遇到令人头痛欲裂的模板引擎中`ContextPath`处理
|
||||
6. ……
|
||||
|
||||
你马上就会发现,写个监控页你一下午就可以搞定,然而这个登录页你却可能需要花上两三天的时间,这是一笔及其不划算的时间浪费
|
||||
|
||||
那么现在你可能就会有个疑问,难道就没有什么方法给我的小项目快速增加一个登录功能吗?
|
||||
|
||||
Sa-Token-Quick-Login便是为了解决这个问题!
|
||||
|
||||
|
||||
### 适用场景
|
||||
|
||||
Sa-Token-Quick-Login 旨在用最小的成本为项目增加一个登录认证功能
|
||||
|
||||
- **简单**:只需要引入一个依赖便可为系统注入登录功能,快速、简单、零代码!
|
||||
- **不可定制**:由于登录页面不可定制,所以Sa-Token-Quick-Login非常不适合普通项目的登录认证模块,STQL也无意去解决所有项目的登录认证模块
|
||||
|
||||
Sa-Token-Quick-Login的定位是这样的场景:你的项目需要一个登录认证功能、这个认证页面可以不华丽、可以烂,但是一定要有,同时你又不想花费太多的时间浪费在登录页面上,
|
||||
那么你便可以尝试一下`Sa-Token-Quick-Login`
|
||||
|
||||
|
||||
### 集成步骤
|
||||
首先我们需要创建一个SpringBoot的demo项目,比如:`sa-token-demo-quick-login`
|
||||
|
||||
##### 1、添加pom依赖
|
||||
``` xml
|
||||
<!-- Sa-Token-Quick-Login 插件 -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-quick-login</artifactId>
|
||||
<version>1.18.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
##### 2、启动类
|
||||
``` java
|
||||
@SpringBootApplication
|
||||
public class SaTokenQuickDemoApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SaTokenQuickDemoApplication.class, args);
|
||||
|
||||
System.out.println("\n------ 启动成功 ------");
|
||||
System.out.println("name: " + SaQuickManager.getConfig().getName());
|
||||
System.out.println("pwd: " + SaQuickManager.getConfig().getPwd());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
##### 3、新建测试Controller
|
||||
``` java
|
||||
/**
|
||||
* 测试专用Controller
|
||||
*/
|
||||
@RestController
|
||||
public class TestController {
|
||||
// 浏览器访问测试: http://localhost:8081
|
||||
@RequestMapping({"/", "/index"})
|
||||
public String login(String username, String password) {
|
||||
String str = "<br />"
|
||||
+ "<h1 style='text-align: center;'>资源页 (登录后才可进入本页面) </h1>"
|
||||
+ "<hr/>"
|
||||
+ "<p style='text-align: center;'> Sa-Token " + SaTokenConsts.VERSION_NO + " </p>";
|
||||
return str;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 测试访问
|
||||
启动项目,使用浏览器访问:`http://localhost:8081`,首次访问时,由于处于未登录状态,会被强制进入登录页面
|
||||
|
||||

|
||||
|
||||
使用默认账号:`sa / 123456`进行登录,会看到资源页面
|
||||
|
||||

|
||||
|
||||
|
||||
### 可配置信息
|
||||
你可以在yml中添加如下配置
|
||||
``` java
|
||||
# Sa-Token-Quick-Login 配置
|
||||
sa:
|
||||
# 登录账号
|
||||
name: sa
|
||||
# 登录密码
|
||||
pwd: 123456
|
||||
# 是否自动随机生成账号密码 (此项为true时, name与pwd失效)
|
||||
auto: false
|
||||
# 是否开启全局认证(关闭后将不再强行拦截)
|
||||
auth: true
|
||||
# 登录页标题
|
||||
title: Sa-Token 登录
|
||||
# 是否显示底部版权信息
|
||||
copr: true
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
**注:**示例源码在`/sa-token-demo/sa-token-demo-quick-login`目录下,可结合源码查看学习
|
||||
|
||||
|
||||
|
||||
### 使用独立jar包运行
|
||||
使用`sa-token-quick-login`只需引入一个依赖即可为系统注入登录模块,现在我们更进一步,将这个项目打成一个独立的jar包
|
||||
|
||||
通过这个jar包,我们可以方便的部署任意静态网站!做到真正的零编码注入登录功能。
|
||||
|
||||
|
||||
##### 打包步骤
|
||||
|
||||
首先放上懒人链接:[sa-quick-dist.jar](https://gitee.com/dromara/sa-token/attach_files/695353/download) ,不想手动操作的同学可以直接点此链接下载打包后的jar文件
|
||||
|
||||
1、首先将 `sa-token-demo-quick-login` 模块添加到顶级父模块的`<modules>`节点中
|
||||
|
||||
``` xml
|
||||
<!-- 所有模块 -->
|
||||
<modules>
|
||||
<module>sa-token-core</module>
|
||||
<module>sa-token-starter</module>
|
||||
<module>sa-token-plugin</module>
|
||||
<module>sa-token-demo\sa-token-demo-quick-login</module>
|
||||
</modules>
|
||||
```
|
||||
|
||||
2、在项目根目录进入cmd执行打包命令
|
||||
|
||||
``` cmd
|
||||
mvn clean package
|
||||
```
|
||||
|
||||
3、进入`\sa-token-demo\sa-token-demo-quick-login\target` 文件夹,找到打包好的jar文件
|
||||
|
||||
``` cmd
|
||||
sa-token-demo-quick-login-0.0.1-SNAPSHOT.jar
|
||||
```
|
||||
|
||||
4、我们将其重命名为`sa-quick-dist.jar`,现在这个jar包就是我们的最终程序,我们在这个`\target`目录直接进入cmd,执行如下命令启动jar包
|
||||
|
||||
``` cmd
|
||||
java -jar sa-quick-dist.jar
|
||||
```
|
||||
|
||||
5、测试访问,根据控制台输出提示,我们使用浏览器访问测试
|
||||
|
||||
``` java
|
||||
http://localhost:8080
|
||||
```
|
||||
|
||||
如果可以进入登录界面,则代表打包运行成功 <br>
|
||||
当然仅仅运行成功还不够,下面我们演示一下如何使用这个jar包进行静态网站部署
|
||||
|
||||
|
||||
### 所有功能示例
|
||||
|
||||
##### Case 1. 指定静态资源路径
|
||||
``` cmd
|
||||
java -jar sa-quick-dist.jar --sa.dir file:E:\www
|
||||
```
|
||||
使用dir参数指定`E:\www`目录作为资源目录进行部署 (现在我们可以通过浏览器访问`E:\www`目录下的文件了!)
|
||||
|
||||
##### Case 2. 指定登录名与密码
|
||||
``` cmd
|
||||
java -jar sa-quick-dist.jar --sa.name=zhang --sa.pwd=zhang123
|
||||
```
|
||||
现在,默认的账号`sa/123456`将被废弃,而是使用`zhang/zhang123`进行账号校验
|
||||
|
||||
##### Case 3. 指定其自动生成账号密码
|
||||
``` cmd
|
||||
java -jar sa-quick-dist.jar --sa.auto=true
|
||||
```
|
||||
每次启动时随机生成账号密码(会在启动成功时打印到控制台上)
|
||||
|
||||
##### Case 4. 指定登录页的标题
|
||||
``` cmd
|
||||
java -jar sa-quick-dist.jar --sa.title="XXX 系统登录"
|
||||
```
|
||||
|
||||
##### Case 5. 关闭账号校验,仅作为静态资源部署使用
|
||||
``` cmd
|
||||
java -jar sa-quick-dist.jar --sa.auth=false
|
||||
```
|
||||
|
||||
##### Case 6. 关闭账号校验,仅作为静态资源部署使用
|
||||
``` cmd
|
||||
java -jar sa-quick-dist.jar --sa.auth=false
|
||||
```
|
||||
|
||||
##### Case 7. 指定启动端口(默认8080)
|
||||
``` cmd
|
||||
java -jar sa-quick-dist.jar --server.port=80
|
||||
```
|
||||
|
||||
注:所有参数可组合使用
|
||||
|
||||
|
||||
### 使用SpringBoot默认资源路径
|
||||
SpringBoot默认开放了一些路径作为资源目录,比如`classpath:/static/`,
|
||||
怎么使用呢?我们只需要在jar包同目录创建一个`\static`文件夹,将静态资源文件复制到此目录下,然后启动jar包即可访问
|
||||
|
||||
同时,我们还可以在jar包同目录创建yml配置文件,来覆盖jar包内的yml配置,如下图所示:
|
||||
|
||||

|
||||
|
||||
例如如上目录中`/static`中有一个`1.jpg`文件,我们启动jar包后访问`http://localhost:8080/1.jpg`即可查看到此文件,这是Springboot自带的功能,在此不再赘述
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SpringBoot 集成 Sa-Token 示例
|
||||
|
||||
本篇将带你从零开始集成sa-token,从而让你快速熟悉sa-token的使用姿势 <br>
|
||||
整合示例在官方仓库的`/sa-token-demo-springboot`文件夹下,如遇到难点可结合源码进行测试学习
|
||||
整合示例在官方仓库的`/sa-token-demo/sa-token-demo-springboot`文件夹下,如遇到难点可结合源码进行测试学习
|
||||
|
||||
---
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
WebFlux基于Reactor响应式模型开发,有着与标准ServletAPI完全不同的底层架构,因此要适配WebFlux, 必须提供与Reactor相关的整合实现,
|
||||
本篇将以WebFlux为例,展示sa-token与Reactor响应式模型web框架相整合的示例, **你可以用同样方式去对接其它Reactor模型Web框架**(Netty、Soul、Gateway等)
|
||||
|
||||
整合示例在官方仓库的`/sa-token-demo-webflux`文件夹下,如遇到难点可结合源码进行测试学习
|
||||
整合示例在官方仓库的`/sa-token-demo/sa-token-demo-webflux`文件夹下,如遇到难点可结合源码进行测试学习
|
||||
|
||||
---
|
||||
|
||||
|
@ -1,58 +1,56 @@
|
||||
# 注解式鉴权
|
||||
---
|
||||
|
||||
有同学表示:尽管使用代码鉴权非常方便,但是我仍希望可以把鉴权逻辑和业务逻辑分离开来,我可以使用注解鉴权吗?<br>
|
||||
当然可以!身为自诩java最强权限认证框架,怎么能少的了注解鉴权这一标配功能呢?
|
||||
有同学表示:尽管使用代码鉴权非常方便,但是我仍希望把鉴权逻辑和业务逻辑分离开来,我可以使用注解鉴权吗?当然可以!<br>
|
||||
|
||||
注解鉴权 —— 优雅的将鉴权与业务代码分离!
|
||||
|
||||
- `@SaCheckLogin`: 标注在方法或类上,当前会话必须处于登录状态才可通过校验
|
||||
- `@SaCheckRole("admin")`: 标注在方法或类上,当前会话必须具有指定角色标识才能通过校验
|
||||
- `@SaCheckPermission("user:add")`: 标注在方法或类上,当前会话必须具有指定权限才能通过校验
|
||||
|
||||
sa-token内置两种模式完成注解鉴权,分别是`AOP模式`和`拦截器模式`, 为了避免不必要的性能浪费,这两种模式默认都处于关闭状态 <br>
|
||||
因此如若使用注解鉴权,你必须选择其一进行注册
|
||||
Sa-Token使用全局拦截器完成注解鉴权功能,为了不为项目带来不必要的性能负担,拦截器默认处于关闭状态<br>
|
||||
因此,为了使用注解鉴权,你必须手动将sa-token的全局拦截器注册到你项目中
|
||||
|
||||
<!-- Sa-Token内置两种模式完成注解鉴权,分别是`拦截器模式`和`AOP模式`, 为了避免不必要的性能浪费,这两种模式默认都处于关闭状态 <br>
|
||||
因此如若使用注解鉴权,你必须选择其一进行注册 -->
|
||||
|
||||
|
||||
## 1、使用AOP模式
|
||||
### 1、注册拦截器
|
||||
以`SpringBoot2.0`为例, 新建配置类`SaTokenConfigure.java`
|
||||
|
||||
首先在`pom.xml`里添加依赖:
|
||||
|
||||
``` xml
|
||||
<!-- sa-token整合SpringAOP实现注解鉴权 -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-aop</artifactId>
|
||||
<version>1.18.0</version>
|
||||
</dependency>
|
||||
``` java
|
||||
@Configuration
|
||||
public class SaTokenConfigure implements WebMvcConfigurer {
|
||||
// 注册sa-token的注解拦截器,打开注解式鉴权功能
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
|
||||
}
|
||||
}
|
||||
```
|
||||
保证此类被`springboot`启动类扫描到即可
|
||||
|
||||
|
||||
### 2、使用注解鉴权
|
||||
然后我们就可以愉快的使用注解鉴权:
|
||||
|
||||
**登录验证**
|
||||
|
||||
``` java
|
||||
// 注解式鉴权:当前会话必须登录才能通过
|
||||
// 登录认证:当前会话必须登录才能通过
|
||||
@SaCheckLogin
|
||||
@RequestMapping("info")
|
||||
public String info() {
|
||||
return "查询用户信息";
|
||||
}
|
||||
```
|
||||
|
||||
**角色验证**
|
||||
|
||||
``` java
|
||||
// 注解式鉴权:当前会话必须具有指定角色标识才能通过
|
||||
// 角色认证:当前会话必须具有指定角色标识才能通过
|
||||
@SaCheckRole("super-admin")
|
||||
@RequestMapping("add")
|
||||
public String add() {
|
||||
return "用户增加";
|
||||
}
|
||||
```
|
||||
|
||||
**权限验证**
|
||||
|
||||
``` java
|
||||
// 注解式鉴权:当前会话必须具有指定权限才能通过
|
||||
// 权限认证:当前会话必须具有指定权限才能通过
|
||||
@SaCheckPermission("user-add")
|
||||
@RequestMapping("add")
|
||||
public String add() {
|
||||
@ -60,10 +58,10 @@ public String add() {
|
||||
}
|
||||
```
|
||||
|
||||
注:以上两个注解都可以加在类上,代表为这个类所有方法进行鉴权
|
||||
注:以上注解都可以加在类上,代表为这个类所有方法进行鉴权
|
||||
|
||||
|
||||
#### 设定校验模式
|
||||
### 3、设定校验模式
|
||||
`@SaCheckRole`与`@SaCheckPermission`注解可设置校验模式,例如:
|
||||
``` java
|
||||
// 注解式鉴权:只要具有其中一个权限即可通过校验
|
||||
@ -81,28 +79,10 @@ mode有两种取值:
|
||||
|
||||
|
||||
|
||||
## 2、使用拦截器模式
|
||||
使用AOP方式需要引入新的pom依赖,与此相比,拦截器模式显的更加轻量级 <br>
|
||||
你只需要将sa-token的注解校验拦截器注册到你的项目中即可打开注解鉴权功能 <br>
|
||||
以`SpringBoot2.0`为例, 新建配置类`SaTokenConfigure.java`
|
||||
|
||||
``` java
|
||||
@Configuration
|
||||
public class SaTokenConfigure implements WebMvcConfigurer {
|
||||
// 注册sa-token的注解拦截器,打开注解式鉴权功能
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
|
||||
}
|
||||
}
|
||||
```
|
||||
保证此类被`springboot`启动类扫描到即可
|
||||
|
||||
|
||||
#### 注意事项:
|
||||
- 使用AOP模式,可以将注解写在任意层级,使用拦截器模式,只能把注解写在`Controller层`上 <br>
|
||||
- 拦截器模式和AOP模式不可同时集成,否则会在`Controller层`发生一个注解校验两次的bug
|
||||
### 4、在业务逻辑层使用注解鉴权
|
||||
疑问:我能否将注解写在其它架构层呢,比如业务逻辑层?
|
||||
|
||||
使用拦截器模式,只能在`Controller层`进行注解鉴权,如需在任意层级使用注解鉴权,请参考:[AOP注解鉴权](/plugin/aop-at)
|
||||
|
||||
|
||||
|
||||
|
@ -32,7 +32,7 @@ public class SaTokenConfigure {
|
||||
* 注册 [sa-token全局过滤器]
|
||||
*/
|
||||
@Bean
|
||||
public SaServletFilter getSaReactorFilter() {
|
||||
public SaServletFilter getSaServletFilter() {
|
||||
return new SaServletFilter()
|
||||
|
||||
// 指定 拦截路由 与 放行路由
|
||||
|
@ -65,7 +65,7 @@ public class StpInterfaceImpl implements StpInterface {
|
||||
}
|
||||
```
|
||||
|
||||
可参考代码:[码云:StpInterfaceImpl.java](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo-springboot/src/main/java/com/pj/satoken/StpInterfaceImpl.java)
|
||||
可参考代码:[码云:StpInterfaceImpl.java](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/satoken/StpInterfaceImpl.java)
|
||||
|
||||
<!-- todo: 缓存逻辑 -->
|
||||
|
||||
@ -114,7 +114,7 @@ StpUtil.checkRoleOr("super-admin", "shop-admin");
|
||||
|
||||
### 拦截全局异常
|
||||
有同学要问,鉴权失败,抛出异常,然后呢?要把异常显示给用户看吗?**当然不可以!** <br>
|
||||
你可以创建一个全局异常拦截器,统一返回给前端的格式,参考:[码云:GlobalException.java](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo-springboot/src/main/java/com/pj/test/GlobalException.java)
|
||||
你可以创建一个全局异常拦截器,统一返回给前端的格式,参考:[码云:GlobalException.java](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/test/GlobalException.java)
|
||||
|
||||
|
||||
### 权限通配符
|
||||
|
@ -217,7 +217,9 @@
|
||||
<a href="https://www.yangxuwang.com/" target="_blank">
|
||||
<img src="https://oss.dev33.cn/sa-token/com/shouxin.png">
|
||||
</a>
|
||||
|
||||
<a href="https://www.ec-sudo.com/" target="_blank">
|
||||
<img src="https://oss.dev33.cn/sa-token/com/shudukeji.png">
|
||||
</a>
|
||||
</div>
|
||||
<div style="height: 10px; clear: both;"></div>
|
||||
<p style="color: #666;">
|
||||
|
12
sa-token-plugin/.gitignore
vendored
Normal file
12
sa-token-plugin/.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
target/
|
||||
|
||||
node_modules/
|
||||
bin/
|
||||
.settings/
|
||||
unpackage/
|
||||
.classpath
|
||||
.project
|
||||
|
||||
.factorypath
|
||||
|
||||
.idea/
|
@ -15,11 +15,13 @@
|
||||
<artifactId>sa-token-plugin</artifactId>
|
||||
<description>sa-token plugins</description>
|
||||
|
||||
<!-- 所有子模块 -->
|
||||
<modules>
|
||||
<module>sa-token-dao-redis</module>
|
||||
<module>sa-token-dao-redis-jackson</module>
|
||||
<module>sa-token-spring-aop</module>
|
||||
<module>sa-token-oauth2</module>
|
||||
<!-- <module>sa-token-oauth2</module> -->
|
||||
<module>sa-token-quick-login</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
12
sa-token-plugin/sa-token-quick-login/.gitignore
vendored
Normal file
12
sa-token-plugin/sa-token-quick-login/.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
target/
|
||||
|
||||
node_modules/
|
||||
bin/
|
||||
.settings/
|
||||
unpackage/
|
||||
.classpath
|
||||
.project
|
||||
|
||||
.factorypath
|
||||
|
||||
.idea/
|
40
sa-token-plugin/sa-token-quick-login/pom.xml
Normal file
40
sa-token-plugin/sa-token-quick-login/pom.xml
Normal file
@ -0,0 +1,40 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-plugin</artifactId>
|
||||
<version>1.18.0</version>
|
||||
</parent>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>sa-token-quick-login</name>
|
||||
<artifactId>sa-token-quick-login</artifactId>
|
||||
<description>sa-token-quick-login</description>
|
||||
|
||||
<dependencies>
|
||||
<!-- sa-token-spring-boot-starter -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-starter</artifactId>
|
||||
<version>${sa-token-version}</version>
|
||||
</dependency>
|
||||
<!-- 视图引擎 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
<version>2.0.0.RELEASE</version>
|
||||
</dependency>
|
||||
<!-- spring-boot-configuration -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<version>2.0.0.RELEASE</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,92 @@
|
||||
package cn.dev33.satoken.quick;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import cn.dev33.satoken.exception.NotLoginException;
|
||||
import cn.dev33.satoken.filter.SaServletFilter;
|
||||
import cn.dev33.satoken.quick.config.SaQuickConfig;
|
||||
import cn.dev33.satoken.quick.web.SaQuickController;
|
||||
import cn.dev33.satoken.spring.SpringMVCUtil;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaTokenConsts;
|
||||
|
||||
/**
|
||||
* 自动注入
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
@Import({ SaQuickController.class })
|
||||
public class SaQuickBean implements WebMvcConfigurer {
|
||||
|
||||
/**
|
||||
* quick-login 配置
|
||||
*
|
||||
* @return see note
|
||||
*/
|
||||
@Bean
|
||||
@ConfigurationProperties(prefix = "sa")
|
||||
public SaQuickConfig getSaQuickConfig() {
|
||||
return new SaQuickConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* 注入quick-login 配置
|
||||
*
|
||||
* @param saQuickConfig 配置对象
|
||||
*/
|
||||
@Autowired
|
||||
public void setSaQuickConfig(SaQuickConfig saQuickConfig) {
|
||||
SaQuickManager.setConfig(saQuickConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册 [sa-token全局过滤器]
|
||||
*
|
||||
* @return see note
|
||||
*/
|
||||
@Bean
|
||||
@Order(SaTokenConsts.ASSEMBLY_ORDER - 1)
|
||||
public SaServletFilter getSaServletFilter() {
|
||||
return new SaServletFilter().
|
||||
|
||||
// 拦截路由 & 放行路由
|
||||
addInclude("/**").addExclude("/favicon.ico", "/saLogin", "/doLogin", "/sa-res/**").
|
||||
|
||||
// 认证函数: 每次请求执行
|
||||
setAuth(r -> {
|
||||
// System.out.println("---------- 进入sa-token全局认证 -----------");
|
||||
|
||||
// 未登录时直接转发到login.html页面
|
||||
if (SaQuickManager.getConfig().getAuth() && StpUtil.isLogin() == false) {
|
||||
try {
|
||||
HttpServletRequest request = SpringMVCUtil.getRequest();
|
||||
HttpServletResponse response = SpringMVCUtil.getResponse();
|
||||
request.getRequestDispatcher("/saLogin").forward(request, response);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 抛出异常,不再继续执行
|
||||
throw NotLoginException.newInstance(StpUtil.getLoginKey(), "");
|
||||
}
|
||||
|
||||
}).
|
||||
|
||||
// 异常处理函数:每次认证函数发生异常时执行此函数
|
||||
setError(e -> {
|
||||
// System.out.println("---------- 进入sa-token异常处理 -----------");
|
||||
return e.getMessage();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package cn.dev33.satoken.quick;
|
||||
|
||||
import cn.dev33.satoken.quick.config.SaQuickConfig;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
/**
|
||||
* SaQuickManager
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaQuickManager {
|
||||
|
||||
/**
|
||||
* 配置文件 Bean
|
||||
*/
|
||||
private static SaQuickConfig config;
|
||||
public static void setConfig(SaQuickConfig config) {
|
||||
SaQuickManager.config = config;
|
||||
// 如果配置了随机密码
|
||||
if(config.getAuto()) {
|
||||
config.setName(SaFoxUtil.getRandomString(8));
|
||||
config.setPwd(SaFoxUtil.getRandomString(8));
|
||||
}
|
||||
}
|
||||
public static SaQuickConfig getConfig() {
|
||||
if (config == null) {
|
||||
synchronized (SaQuickManager.class) {
|
||||
if (config == null) {
|
||||
setConfig(new SaQuickConfig());
|
||||
}
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package cn.dev33.satoken.quick.config;
|
||||
|
||||
/**
|
||||
* sa-quick 配置类 Model
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaQuickConfig {
|
||||
|
||||
/** 是否开启全局认证 */
|
||||
private Boolean auth = true;
|
||||
|
||||
/** 用户名 */
|
||||
private String name = "sa";
|
||||
|
||||
/** 密码 */
|
||||
private String pwd = "123456";
|
||||
|
||||
/** 是否自动生成一个账号和密码 */
|
||||
private Boolean auto = false;
|
||||
|
||||
/** 登录页面的标题 */
|
||||
private String title = "Sa-Token 登录";
|
||||
|
||||
/** 是否显示底部版权信息 */
|
||||
private Boolean copr = true;
|
||||
|
||||
|
||||
public Boolean getAuth() {
|
||||
return auth;
|
||||
}
|
||||
|
||||
public void setAuth(Boolean auth) {
|
||||
this.auth = auth;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getPwd() {
|
||||
return pwd;
|
||||
}
|
||||
|
||||
public void setPwd(String pwd) {
|
||||
this.pwd = pwd;
|
||||
}
|
||||
|
||||
public Boolean getAuto() {
|
||||
return auto;
|
||||
}
|
||||
|
||||
public void setAuto(Boolean auto) {
|
||||
this.auto = auto;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public Boolean getCopr() {
|
||||
return copr;
|
||||
}
|
||||
|
||||
public void setCopr(Boolean copr) {
|
||||
this.copr = copr;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SaQuickConfig [auth=" + auth + ", name=" + name + ", pwd=" + pwd + ", auto=" + auto + ", title=" + title
|
||||
+ ", copr=" + copr + "]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package cn.dev33.satoken.quick.web;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import cn.dev33.satoken.quick.SaQuickManager;
|
||||
import cn.dev33.satoken.quick.config.SaQuickConfig;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
/**
|
||||
* 登录Controller
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
@Controller
|
||||
public class SaQuickController {
|
||||
|
||||
/**
|
||||
* 进入登录页面
|
||||
* @param request see note
|
||||
* @return see note
|
||||
*/
|
||||
@GetMapping("/saLogin")
|
||||
public String saLogin(HttpServletRequest request) {
|
||||
request.setAttribute("cfg", SaQuickManager.getConfig());
|
||||
return "sa-login.html";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 登录接口
|
||||
* @param name 账号
|
||||
* @param pwd 密码
|
||||
* @return 是否登录成功
|
||||
*/
|
||||
@PostMapping("/doLogin")
|
||||
@ResponseBody
|
||||
public Map<String, Object> doLogin(String name, String pwd) {
|
||||
|
||||
// 参数完整性校验
|
||||
if(SaFoxUtil.isEmpty(name) || SaFoxUtil.isEmpty(pwd)) {
|
||||
return getResult(500, "请输入账号和密码", null);
|
||||
}
|
||||
|
||||
// 密码校验
|
||||
SaQuickConfig config = SaQuickManager.getConfig();
|
||||
if(name.equals(config.getName()) && pwd.equals(config.getPwd())) {
|
||||
StpUtil.setLoginId(config.getName());
|
||||
return getResult(200, "ok", StpUtil.getTokenInfo());
|
||||
} else {
|
||||
// 校验失败
|
||||
return getResult(500, "账号或密码输入错误", null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Map<String, Object> getResult(int code, String msg, Object data) {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("code", code);
|
||||
map.put("msg", msg);
|
||||
map.put("data", data);
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.dev33.satoken.quick.SaQuickBean
|
2
sa-token-plugin/sa-token-quick-login/src/main/resources/static/sa-res/jquery.min.js
vendored
Normal file
2
sa-token-plugin/sa-token-quick-login/src/main/resources/static/sa-res/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,2 @@
|
||||
/*! layer mobile-v2.0.0 Web弹层组件 MIT License http://layer.layui.com/mobile By 贤心 */
|
||||
;!function(e){"use strict";var t=document,n="querySelectorAll",i="getElementsByClassName",a=function(e){return t[n](e)},s={type:0,shade:!0,shadeClose:!0,fixed:!0,anim:"scale"},l={extend:function(e){var t=JSON.parse(JSON.stringify(s));for(var n in e)t[n]=e[n];return t},timer:{},end:{}};l.touch=function(e,t){e.addEventListener("click",function(e){t.call(this,e)},!1)};var r=0,o=["layui-m-layer"],c=function(e){var t=this;t.config=l.extend(e),t.view()};c.prototype.view=function(){var e=this,n=e.config,s=t.createElement("div");e.id=s.id=o[0]+r,s.setAttribute("class",o[0]+" "+o[0]+(n.type||0)),s.setAttribute("index",r);var l=function(){var e="object"==typeof n.title;return n.title?'<h3 style="'+(e?n.title[1]:"")+'">'+(e?n.title[0]:n.title)+"</h3>":""}(),c=function(){"string"==typeof n.btn&&(n.btn=[n.btn]);var e,t=(n.btn||[]).length;return 0!==t&&n.btn?(e='<span yes type="1">'+n.btn[0]+"</span>",2===t&&(e='<span no type="0">'+n.btn[1]+"</span>"+e),'<div class="layui-m-layerbtn">'+e+"</div>"):""}();if(n.fixed||(n.top=n.hasOwnProperty("top")?n.top:100,n.style=n.style||"",n.style+=" top:"+(t.body.scrollTop+n.top)+"px"),2===n.type&&(n.content='<i></i><i class="layui-m-layerload"></i><i></i><p>'+(n.content||"")+"</p>"),n.skin&&(n.anim="up"),"msg"===n.skin&&(n.shade=!1),s.innerHTML=(n.shade?"<div "+("string"==typeof n.shade?'style="'+n.shade+'"':"")+' class="layui-m-layershade"></div>':"")+'<div class="layui-m-layermain" '+(n.fixed?"":'style="position:static;"')+'><div class="layui-m-layersection"><div class="layui-m-layerchild '+(n.skin?"layui-m-layer-"+n.skin+" ":"")+(n.className?n.className:"")+" "+(n.anim?"layui-m-anim-"+n.anim:"")+'" '+(n.style?'style="'+n.style+'"':"")+">"+l+'<div class="layui-m-layercont">'+n.content+"</div>"+c+"</div></div></div>",!n.type||2===n.type){var d=t[i](o[0]+n.type),y=d.length;y>=1&&layer.close(d[0].getAttribute("index"))}document.body.appendChild(s);var u=e.elem=a("#"+e.id)[0];n.success&&n.success(u),e.index=r++,e.action(n,u)},c.prototype.action=function(e,t){var n=this;e.time&&(l.timer[n.index]=setTimeout(function(){layer.close(n.index)},1e3*e.time));var a=function(){var t=this.getAttribute("type");0==t?(e.no&&e.no(),layer.close(n.index)):e.yes?e.yes(n.index):layer.close(n.index)};if(e.btn)for(var s=t[i]("layui-m-layerbtn")[0].children,r=s.length,o=0;o<r;o++)l.touch(s[o],a);if(e.shade&&e.shadeClose){var c=t[i]("layui-m-layershade")[0];l.touch(c,function(){layer.close(n.index,e.end)})}e.end&&(l.end[n.index]=e.end)},e.layer={v:"2.0",index:r,open:function(e){var t=new c(e||{});return t.index},close:function(e){var n=a("#"+o[0]+e)[0];n&&(n.innerHTML="",t.body.removeChild(n),clearTimeout(l.timer[e]),delete l.timer[e],"function"==typeof l.end[e]&&l.end[e](),delete l.end[e])},closeAll:function(){for(var e=t[i](o[0]),n=0,a=e.length;n<a;n++)layer.close(0|e[0].getAttribute("index"))}},"function"==typeof define?define(function(){return layer}):function(){var e=document.scripts,n=e[e.length-1],i=n.src,a=i.substring(0,i.lastIndexOf("/")+1);n.getAttribute("merge")||document.head.appendChild(function(){var e=t.createElement("link");return e.href=a+"need/layer.css?2.0",e.type="text/css",e.rel="styleSheet",e.id="layermcss",e}())}()}(window);
|
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 5.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 701 B |
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
@ -0,0 +1,54 @@
|
||||
*{margin: 0; padding: 0;}
|
||||
body{font-family: Helvetica Neue,Helvetica,PingFang SC,Tahoma,Arial,sans-serif;}
|
||||
::-webkit-input-placeholder{color: #ccc;}
|
||||
|
||||
/* 视图盒子 */
|
||||
.view-box{position: relative; width: 100vw; height: 100vh; overflow: hidden;}
|
||||
/* 背景 EAEFF3 */
|
||||
.bg-1{height: 50%; background: linear-gradient(to bottom right, #0466c5, #3496F5);}
|
||||
.bg-2{height: 50%; background-color: #EAEFF3;}
|
||||
|
||||
/* 渐变背景 */
|
||||
.bg-1{
|
||||
background-size: 500%;
|
||||
background-image: linear-gradient(125deg,#0466c5,#3496F5,#0466c5,#3496F5,#0466c5,#2496F5);
|
||||
animation: bganimation 30s infinite;
|
||||
}
|
||||
@keyframes bganimation{
|
||||
0%{background-position: 0% 50%;}
|
||||
50%{background-position: 100% 50%;}
|
||||
100%{background-position: 0% 50%;}
|
||||
}
|
||||
|
||||
/* 内容盒子 */
|
||||
.content-box{position: absolute; width: 100vw; height: 100vh; top: 0px;}
|
||||
|
||||
/* 登录盒子 */
|
||||
/* .login-box{width: 400px; height: 400px; position: absolute; left: calc(50% - 200px); top: calc(50% - 200px); max-width: 90%; } */
|
||||
.login-box{width: 400px; margin: auto; max-width: 90%; height: 100%;}
|
||||
.login-box{display: flex; align-items: center; text-align: center;}
|
||||
|
||||
/* 表单 */
|
||||
.from-box{flex: 1; padding: 20px 50px; background-color: #FFF;}
|
||||
.from-box{border-radius: 1px; box-shadow: 1px 1px 20px #666;}
|
||||
.from-title{margin-top: 20px; margin-bottom: 30px; text-align: center;}
|
||||
|
||||
/* 输入框 */
|
||||
.from-item{border: 0px #000 solid; margin-bottom: 15px;}
|
||||
.s-input{width: 100%; line-height: 32px; height: 32px; text-indent: 1em; outline: 0; border: 1px #ccc solid; border-radius: 3px; transition: all 0.2s;}
|
||||
.s-input{font-size: 12px;}
|
||||
.s-input:focus{border-color: #409eff}
|
||||
|
||||
/* 登录按钮 */
|
||||
.s-btn{ text-indent: 0; cursor: pointer; background-color: #409EFF; border-color: #409EFF; color: #FFF;}
|
||||
.s-btn:hover{background-color: #50aEFF;}
|
||||
|
||||
/* 重置按钮 */
|
||||
.reset-box{text-align: left; font-size: 12px;}
|
||||
.reset-box a{text-decoration: none;}
|
||||
.reset-box a:hover{text-decoration: underline;}
|
||||
|
||||
/* loading框样式 */
|
||||
.ajax-layer-load.layui-layer-dialog{min-width: 0px !important; background-color: rgba(0,0,0,0.85);}
|
||||
.ajax-layer-load.layui-layer-dialog .layui-layer-content{padding: 10px 20px 10px 40px; color: #FFF;}
|
||||
.ajax-layer-load.layui-layer-dialog .layui-layer-content .layui-layer-ico{width: 20px; height: 20px; background-size: 20px 20px; top: 12px; }
|
@ -0,0 +1,65 @@
|
||||
// sa
|
||||
var sa = {};
|
||||
|
||||
// 打开loading
|
||||
sa.loading = function(msg) {
|
||||
layer.closeAll(); // 开始前先把所有弹窗关了
|
||||
return layer.msg(msg, {icon: 16, shade: 0.3, time: 1000 * 20, skin: 'ajax-layer-load' });
|
||||
};
|
||||
|
||||
// 隐藏loading
|
||||
sa.hideLoading = function() {
|
||||
layer.closeAll();
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------- 登录事件 -----------------------------------
|
||||
|
||||
$('.login-btn').click(function(){
|
||||
sa.loading("正在登录...");
|
||||
// 开始登录
|
||||
setTimeout(function() {
|
||||
$.ajax({
|
||||
url: "doLogin",
|
||||
type: "post",
|
||||
data: {
|
||||
name: $('[name=name]').val(),
|
||||
pwd: $('[name=pwd]').val()
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(res){
|
||||
console.log('返回数据:', res);
|
||||
sa.hideLoading();
|
||||
if(res.code == 200) {
|
||||
layer.msg('登录成功', {anim: 0, icon: 6 });
|
||||
setTimeout(function() {
|
||||
location.reload();
|
||||
}, 800)
|
||||
} else {
|
||||
layer.msg(res.msg, {anim: 6, icon: 2 });
|
||||
}
|
||||
},
|
||||
error: function(xhr, type, errorThrown){
|
||||
sa.hideLoading();
|
||||
if(xhr.status == 0){
|
||||
return layer.alert('无法连接到服务器,请检查网络');
|
||||
}
|
||||
return layer.alert("异常:" + JSON.stringify(xhr));
|
||||
}
|
||||
});
|
||||
}, 400);
|
||||
});
|
||||
|
||||
// 绑定回车事件
|
||||
$('[name=name],[name=pwd]').bind('keypress', function(event){
|
||||
if(event.keyCode == "13") {
|
||||
$('.login-btn').click();
|
||||
}
|
||||
});
|
||||
|
||||
// 输入框获取焦点
|
||||
$("[name=name]").focus();
|
||||
|
||||
// 打印信息
|
||||
var str = "This page is provided by Sa-Token, Please refer to: " + "http://sa-token.dev33.cn/";
|
||||
console.log(str);
|
@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<title>登录</title>
|
||||
<meta charset="utf-8">
|
||||
<base th:href="@{/}" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<link rel="stylesheet" href="./sa-res/login.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="view-box">
|
||||
<div class="bg-1"></div>
|
||||
<div class="bg-2"></div>
|
||||
<div class="content-box">
|
||||
<div class="login-box">
|
||||
<div class="from-box">
|
||||
<h2 class="from-title" th:utext="${cfg.title}"></h2>
|
||||
<div class="from-item">
|
||||
<input class="s-input" name="name" placeholder="请输入账号" />
|
||||
</div>
|
||||
<div class="from-item">
|
||||
<input class="s-input" name="pwd" type="password" placeholder="请输入密码" />
|
||||
</div>
|
||||
<div class="from-item">
|
||||
<button class="s-input s-btn login-btn">登录</button>
|
||||
</div>
|
||||
<div class="from-item reset-box">
|
||||
<a href="javascript: location.reload();" >刷新</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 底部 版权 -->
|
||||
<div style="position: absolute; bottom: 40px; width: 100%; text-align: center; color: #666;" th:if="${cfg.copr}">
|
||||
This page is provided by Sa-Token
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- scripts -->
|
||||
<script src="./sa-res/jquery.min.js"></script>
|
||||
<script src="./sa-res/layer/layer.js"></script>
|
||||
<script src="./sa-res/login.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
12
sa-token-starter/.gitignore
vendored
Normal file
12
sa-token-starter/.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
target/
|
||||
|
||||
node_modules/
|
||||
bin/
|
||||
.settings/
|
||||
unpackage/
|
||||
.classpath
|
||||
.project
|
||||
|
||||
.factorypath
|
||||
|
||||
.idea/
|
@ -15,6 +15,7 @@
|
||||
<artifactId>sa-token-starter</artifactId>
|
||||
<description>sa-token starters</description>
|
||||
|
||||
<!-- 所有子模块 -->
|
||||
<modules>
|
||||
<module>sa-token-servlet</module>
|
||||
<module>sa-token-spring-boot-starter</module>
|
||||
|
Loading…
Reference in New Issue
Block a user