aZ~akJ)MV6mH>Eid-FjwjV9
z+&G2fqjB*k*gYNi42&Bq^-|s}Rvc-L?t9#xxgZVB;b@q3sd<@H5u4R9l(Fxx@)h&MSZ2xgB`+xVVzxIa*{i0L}5CsS54{3vc
zzsww58N$qdVhs5PFBsoFB%|Na1uNLnxNXRiNi18Uvqou`UqW3lBu6;l>Z@Qb$x`OF
zWlEe+Yx*GZG!tY2+1}pXP}6bK@HN+gHKv-d(r4YTA0sHCq0J(nQ|hN|BssKg>2sk)
z#V91#>vNGr?H66b=R3yZ={I1-iH$_PNF|i7BZzBQZ_s=jUXY)dh>W9_$)+8n8jJ
zgb98b&s#%=?iwNwEp*mO1l^S4PNNV)XK0O+>A{Jh0v6qc>Xy*UmPquuuRu%&%+!gg~TS2{uWci1%XhDN9Fyy0EN%^lp8=FNMQyBBVMuwv6Fj4
zRQbIag|Js@6^!;B@!6JEXd6H-0Mm*1*zw&3fkx-ETz$p44lK6SxI-&qYT)j2-bM*#
ze}st3!R_-dWK3m@iq@_n7{h}4EScerygRuzO4mD(hhyr9*%_GzU>!(&;{E>TG4L5@KLx7LWOB7HSA%IKqk7~YP-qr+w=Dys{
zYsK^ly%%s4;pA9-WpX1Q>B9PqID`nVGOF=BgL`wK@$&R~79Pl@+&U{HyW1Wr^=N*}
zG@HirywnlOsG?v)c=?UhHm0ebsSnXYh=4NNY~XqX>&OwN!rNWT=~u}iOw!8d9@@g#jylcOX@l5h#944*%h5WR+GrnID_ExNegei>6J43
zHzJF8VS^m7NuwFeoP1Yv^i3#^u60X|bX0B7g{jx#%kZ@0hjEWHG&_ahuV79XU~nk|
zRw=H?V~8!vWXSgjrGr5;o#%^DhLS?~VP0V9Z@s~>H;ge@deK@#Slp<9zLpSTQKz@W
zA$Z<`)VM#Z9Eq3!t9@+Q4gYP-Ic&t|n{^q4?4DS$>wE`wI9A=D?X7B`alm@xf``of
zg7DT`(m+~&BIN)N?D;xuGTNerJ=tR8JWgdCJUa}wB79tjaLSFK;@mE=alvxmfKcIb
zdsGlb7{U8P%3kUUjZh7Cdv{tS%18=WB(I1f^2APMp^oj%BPdKOf4awGyhvyy|I8zI!!D
zH$I!KtiG;2oEKmmC`y~&r80wRYRr_`YBxYTa
z;5ZGk17#y)ob(!^FrHW&%-b>yw|V&V!LN3BttSChIie;-U&HA`%gEToz;ZD-Obf
zEw#JhTm1+J%)#_w;vmWM5_J?7C6~hnv3B-j3-bDe%v^>(NtuJnZd$Ie(k4+GR&Mzr
zar#&bB!@{Z2dVhx7-BmAWDv)w`le^>kXorjh+`R3Io7xuvGvQD;SMK;_-eCn@DEG2
z+*fc$7jSay{>W4K`{Wq-N5Bg4?+kkXSh9azNdYG4SwN@?C%^<9X{Otk-7SZqfw@+$
zSUbU{Eb^YB;vIAJ2#tM}tBQZ>xQRJ)eudh~e{h92*V6Sei!LM|E`Y+dyZVW{5
z>c={_uRAA4XG?a+qaWGyu?hMC*OU?$P9NP5&sHGc2#eL++$hoXbNSm31P2
zR$QyRbKFZCAqJsN6alX^rc#X~QS%`I#l}q&SzT*`L{c4X{hUQF#lWXe-w9J#2i>Hb
zb&|B!1l=bU%N)(x;>|p!X{IRWclq&f%xqi^rCi@;Pmgm;buF1Xvq)wo>-6Q+1P{>I
z7T+#48~5G$+q32Uen9N3my^?+vF*C80TryOrf^m-TbV>>T68bmINdbz$5hMFy9AV)
z>BAtXvMRSK=MSyZ*mwJ&EcUBy7kCdM)i=JI^$c(dr~)!ee>pb(*(!$cKSb)$6-B|y
z0?@?G+j^AQ>TTW3^d*bQhUYc~OWb8|2tEiZw#?QZI^{CUr;oMLaWQi!V7D*tpl`GA
za~5wI??4WTt+YA`v_~9<92VRU*a01eGh2XNUpI2t!|ZA=Id;0bOor4$1ryq)+>nib
zNH}p?!|Vg$*@ztW&v2N+gpj4*GC=HPfWe>uFZ@~%YWQW=p!}>IUxiDKdY?4s4U(Xq
zXG_KClpdYC!f9M&s*pD#NxObp{AYwB)!!o9seBB)b0~^=3`X5gymGp?xE-Di!9l~{R|6vkjRtiQ_1w#
zBxP}KS{@@LrkIA!>B8U4WYifdX7{NEtqaYLvu`hstT`M!ys1``m4@TsgzpTt-paQz
zYfe@if`g`zRv-}}v#^*|>IqoBlVQgf+*D=(7H-7&hB?(njl+tmG7OPg7r`l%XKCu)
zuspLUB{5mhNkKTl)J}ZVp_pu)*F<+Aq8=bEM;N2tZbX&MCq^1C7*k&HIuTL>`T`qp
zpn%1q9aFK;ZJ91nmD);0XRNfqU4%0s+BH
zKVt2I3)5<3hy_2%+XY=O2}Q3L6hIHgB5}r$gfc1PS0f>d#a+-tAt9wYn+kX5D{I`P
za;(?*_->A2`V$OR#%>NTp7UH^Ru?ViNP~H=F{!GQa-@aUb>^fPsTXJzsgfwY9@PMa
zu(v1FkyhDskgKyu{`L_UjOT)29ou;eq|=?u4>V2T7
z7amALOaVAC&*hOB-hRiAT%wtpwlbNWt_fScNsy$0JDS#D$LJphXU($!(`PM>V}exf
z(ju6-iQFxd?~Xdx#7ihOAE%C^uVgdjdtnvOeA`vf(5Po>LxaSm
z{9147IXDU)b|QUQnTYm^FpFhEifHIOK^};3mPv3Os6^JPTiu;#z>6qm^a-d0AT!*r
z6fhr(`XsffB2m?w+t8-u;7Y&vdHB|4PB7m}B*@DnSO^oG)$4l5q(K$FQ^c^+m1h}W
z2s=_C|A6M4dFUg8ZpsWWW2
zlZ7e??j7rcxOAwrLM{O!PPqRPmuJ8zKz|>4gMemMl|I1x4@r3s9xN0ffVK9?kQP?r
zrxuqHp_S&B5f>3wRHBggU0sY<=2KbRjLl5u_@QnS}3jh<(qv7}W3x5}u
z{IAy#AH4(wRP^|@pY-C4;!oS88;PGD$JVQO3zX<<1Uk`fyF$!t(LnwYBVEH}h
z^}hx*;9q|W@k4D8(zE$n%YUHiCnPbTEB50y^$&W-uaN=xk^c+wVG%z@d?5012kr+O
z*{?AN;PC%}_@vqWW8{Yp-jDk>KisZ=4Mo6B{C`CLN%Eg0=qYPl0Altp;J=$d|C+~#
zuYTN0mGBo~fT!X=K|E;+{rFoS8n8a@ut@L(?=_%BWLZiTCphf3o?3yvKd}9?thOP);(lj{u-5l3H=kfzs3J2`41<{;~ob@zpw#MnCO3o
zf7Ao-F})A15gyl>eabFjz{2_yy}ueIJjQ#N-^YblADl|R1`^$$@&4cU|9fpd)NFlR
zc9i57BH&3LFvou)@)zjOnf#NeKV)G28t(vd@h{9Dg-8DRxsNMlJr$>g|3LY%7yYK3
z>0|tddRvc6r92gEGN*}oSI5qF7xWOv?8Rf?^d6Xvk822Hu?{PL6`LE9hJmo9?
zkGMZS`Z4z&r|Udjb`r|}0sACH$G}q0!QnBz57|DCb2FaK1E1>u3jCAcKXK_Hv*Xuz
zul^g{zXAmx)Aqol$1(R$=W^+f7*FHu|Mkfa0sD^wxgR3Aehpi#Kautn_U8vb=FsCP
z$)~9HI)6lc92xm9S|1`TABV9$Jsd3z|0mR+r2dIF5BG;(1K;E~pg$e6|76eOIFYAc
z{OZ48{-6Km-{-(XjLBmU^3yNYu>23=exd&S;>XN+>~?ypSSQ;4FQC8dJdY>g!EN=}
zlkjw5);j*r$iE}`vAy%@g@woEH^4u3rYCNR$Fx2eN*~+1o?ciE-T!aMe-iniTs}5v
wJk%``LWJdwk=4s=8PE{2zFKlLrbg
+ 4.0.0
+ cn.dev33
+ sa-token-demo-springboot
+ 0.0.1-SNAPSHOT
+
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.0.0.RELEASE
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+
+
+ cn.dev33.sa-token
+ sa-token-spring
+ 1.0.0
+ system
+ ${project.basedir}/lib/sa-token-spring-1.0.0.jar
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-redis
+ RELEASE
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ true
+ lib/
+ com.pj.SaTokenDemoApplication
+
+
+
+ lib/sa-token-spring-1.0.0.jar
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+ copy
+ package
+
+ copy-dependencies
+
+
+
+ ${project.build.directory}/lib
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sa-token-demo-springboot/src/main/java/com/pj/SaTokenDemoApplication.java b/sa-token-demo-springboot/src/main/java/com/pj/SaTokenDemoApplication.java
new file mode 100644
index 0000000..384540c
--- /dev/null
+++ b/sa-token-demo-springboot/src/main/java/com/pj/SaTokenDemoApplication.java
@@ -0,0 +1,18 @@
+package com.pj;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+
+import cn.dev33.satoken.spring.SaTokenSetup;
+
+@SaTokenSetup // 标注启动 sa-token
+@SpringBootApplication
+public class SaTokenDemoApplication {
+
+ public static void main(String[] args) throws JsonProcessingException {
+ SpringApplication.run(SaTokenDemoApplication.class, args); // run-->
+ }
+
+}
\ No newline at end of file
diff --git a/sa-token-demo-springboot/src/main/java/com/pj/satoken/SaTokenDaoRedis.java b/sa-token-demo-springboot/src/main/java/com/pj/satoken/SaTokenDaoRedis.java
new file mode 100644
index 0000000..b7a7059
--- /dev/null
+++ b/sa-token-demo-springboot/src/main/java/com/pj/satoken/SaTokenDaoRedis.java
@@ -0,0 +1,91 @@
+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 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);
+ }
+
+
+
+
+
+
+
+
+}
diff --git a/sa-token-demo-springboot/src/main/java/com/pj/satoken/StpCustom.java b/sa-token-demo-springboot/src/main/java/com/pj/satoken/StpCustom.java
new file mode 100644
index 0000000..6de6ce8
--- /dev/null
+++ b/sa-token-demo-springboot/src/main/java/com/pj/satoken/StpCustom.java
@@ -0,0 +1,28 @@
+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