mirror of
https://github.com/PlayEdu/PlayEdu
synced 2025-12-25 20:35:35 +08:00
接入sa-token
This commit is contained in:
@@ -15,20 +15,20 @@
|
||||
*/
|
||||
package xyz.playedu.api.service;
|
||||
|
||||
import xyz.playedu.api.exception.JwtLogoutException;
|
||||
import xyz.playedu.api.types.JWTPayload;
|
||||
import xyz.playedu.api.types.JwtToken;
|
||||
import java.util.HashMap;
|
||||
|
||||
public interface JWTService {
|
||||
JwtToken generate(Integer userId, String iss, String prv);
|
||||
public interface AuthService {
|
||||
String loginUsingId(Integer userId, String loginUrl, String prv);
|
||||
|
||||
boolean isInBlack(String jti);
|
||||
boolean check(String prv);
|
||||
|
||||
void logout(String token, String prv) throws JwtLogoutException;
|
||||
Integer userId();
|
||||
|
||||
void userLogout(String token) throws JwtLogoutException;
|
||||
void logout();
|
||||
|
||||
void adminUserLogout(String token) throws JwtLogoutException;
|
||||
String jti();
|
||||
|
||||
JWTPayload parse(String token, String prv) throws JwtLogoutException;
|
||||
Long expired();
|
||||
|
||||
HashMap<String, String> parse(String token);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2023 杭州白书科技有限公司
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package xyz.playedu.api.service;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public interface BackendAuthService {
|
||||
String loginUsingId(Integer userId, String loginUrl);
|
||||
|
||||
boolean check();
|
||||
|
||||
Integer userId();
|
||||
|
||||
void logout();
|
||||
|
||||
String jti();
|
||||
|
||||
HashMap<String, String> parse(String token);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2023 杭州白书科技有限公司
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package xyz.playedu.api.service;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public interface FrontendAuthService {
|
||||
String loginUsingId(Integer userId, String loginUrl);
|
||||
|
||||
boolean check();
|
||||
|
||||
Integer userId();
|
||||
|
||||
void logout();
|
||||
|
||||
String jti();
|
||||
|
||||
HashMap<String, String> parse(String token);
|
||||
}
|
||||
@@ -19,11 +19,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import xyz.playedu.api.domain.UserLoginRecord;
|
||||
|
||||
/**
|
||||
* @author tengteng
|
||||
* @description 针对表【user_login_records】的数据库操作Service
|
||||
* @createDate 2023-03-10 13:40:33
|
||||
*/
|
||||
public interface UserLoginRecordService extends IService<UserLoginRecord> {
|
||||
UserLoginRecord store(
|
||||
Integer userId,
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2023 杭州白书科技有限公司
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package xyz.playedu.api.service.impl;
|
||||
|
||||
import cn.dev33.satoken.stp.SaLoginConfig;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import xyz.playedu.api.config.AuthConfig;
|
||||
import xyz.playedu.api.service.AuthService;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class AuthServiceImpl implements AuthService {
|
||||
|
||||
@Autowired private AuthConfig authConfig;
|
||||
|
||||
@Override
|
||||
public String loginUsingId(Integer userId, String loginUrl, String prv) {
|
||||
StpUtil.login(
|
||||
userId,
|
||||
SaLoginConfig.setExtra("url", loginUrl)
|
||||
.setExtra("prv", prv)
|
||||
.setExtra(
|
||||
"exp",
|
||||
String.valueOf(
|
||||
System.currentTimeMillis()
|
||||
+ authConfig.getExpired() * 1000L)));
|
||||
return StpUtil.getTokenValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check(String prv) {
|
||||
if (!StpUtil.isLogin()) {
|
||||
return false;
|
||||
}
|
||||
String tokenPrv = (String) StpUtil.getExtra("prv");
|
||||
return prv.equals(tokenPrv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer userId() {
|
||||
return StpUtil.getLoginIdAsInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() {
|
||||
StpUtil.logout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String jti() {
|
||||
return (String) StpUtil.getExtra("rnStr");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long expired() {
|
||||
return (Long) StpUtil.getExtra("exp");
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<String, String> parse(String token) {
|
||||
HashMap<String, String> data = new HashMap<>();
|
||||
data.put("jti", (String) StpUtil.getExtra(token, "rnStr"));
|
||||
data.put("exp", (String) StpUtil.getExtra(token, "exp"));
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2023 杭州白书科技有限公司
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package xyz.playedu.api.service.impl;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import xyz.playedu.api.constant.SystemConstant;
|
||||
import xyz.playedu.api.service.AuthService;
|
||||
import xyz.playedu.api.service.BackendAuthService;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@Service
|
||||
public class BackendAuthServiceImpl implements BackendAuthService {
|
||||
@Autowired private AuthService authService;
|
||||
|
||||
@Override
|
||||
public String loginUsingId(Integer userId, String loginUrl) {
|
||||
return authService.loginUsingId(userId, loginUrl, SystemConstant.JWT_PRV_ADMIN_USER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check() {
|
||||
return authService.check(SystemConstant.JWT_PRV_ADMIN_USER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer userId() {
|
||||
return authService.userId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() {
|
||||
authService.logout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String jti() {
|
||||
return authService.jti();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<String, String> parse(String token) {
|
||||
return authService.parse(token);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2023 杭州白书科技有限公司
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package xyz.playedu.api.service.impl;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import xyz.playedu.api.constant.SystemConstant;
|
||||
import xyz.playedu.api.service.AuthService;
|
||||
import xyz.playedu.api.service.FrontendAuthService;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@Service
|
||||
public class FrontendAuthServiceImpl implements FrontendAuthService {
|
||||
|
||||
@Autowired private AuthService authService;
|
||||
|
||||
@Override
|
||||
public String loginUsingId(Integer userId, String loginUrl) {
|
||||
return authService.loginUsingId(userId, loginUrl, SystemConstant.JWT_PRV_USER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check() {
|
||||
return authService.check(SystemConstant.JWT_PRV_USER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer userId() {
|
||||
return authService.userId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() {
|
||||
authService.logout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String jti() {
|
||||
return authService.jti();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<String, String> parse(String token) {
|
||||
return authService.parse(token);
|
||||
}
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* Copyright 2023 杭州白书科技有限公司
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package xyz.playedu.api.service.impl;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.JwtBuilder;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import xyz.playedu.api.constant.SystemConstant;
|
||||
import xyz.playedu.api.exception.JwtLogoutException;
|
||||
import xyz.playedu.api.service.JWTService;
|
||||
import xyz.playedu.api.types.JWTPayload;
|
||||
import xyz.playedu.api.types.JwtToken;
|
||||
import xyz.playedu.api.util.HelperUtil;
|
||||
import xyz.playedu.api.util.RedisUtil;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class JwtServiceImpl implements JWTService {
|
||||
|
||||
@Value("${playedu.jwt.key}")
|
||||
private String ConfigKey;
|
||||
|
||||
@Value("${playedu.jwt.expire}")
|
||||
private Long ConfigExpire;
|
||||
|
||||
@Value("${playedu.jwt.cache-black-prefix}")
|
||||
private String ConfigCacheBlackPrefix;
|
||||
|
||||
public JwtToken generate(Integer userId, String iss, String prv) {
|
||||
long curTime = System.currentTimeMillis();
|
||||
|
||||
JWTPayload payload = new JWTPayload();
|
||||
payload.setPrv(prv);
|
||||
payload.setIss(iss);
|
||||
payload.setJti(HelperUtil.uuid());
|
||||
payload.setNbf(curTime);
|
||||
payload.setIat(curTime);
|
||||
payload.setExp(curTime + ConfigExpire * 1000);
|
||||
payload.setSub(userId);
|
||||
|
||||
JwtBuilder builder = Jwts.builder();
|
||||
builder.setId(payload.getJti())
|
||||
.setIssuedAt(new Date(payload.getIat()))
|
||||
.claim("prv", payload.getPrv());
|
||||
builder.setExpiration(new Date(payload.getExp())).setIssuer(payload.getIss());
|
||||
builder.setSubject(String.valueOf(payload.getSub()))
|
||||
.setNotBefore(new Date(payload.getNbf()));
|
||||
builder.signWith(getSecretKey());
|
||||
|
||||
JwtToken token = new JwtToken();
|
||||
token.setToken(builder.compact());
|
||||
token.setExpire(payload.getExp() / 1000);
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
public JWTPayload parse(String token, String prv) throws JwtLogoutException {
|
||||
Claims claims = parseToken(token, prv);
|
||||
JWTPayload payload = new JWTPayload();
|
||||
|
||||
payload.setSub(Integer.valueOf(claims.getSubject()));
|
||||
payload.setIss(claims.getIssuer());
|
||||
payload.setPrv((String) claims.get("prv"));
|
||||
payload.setNbf(claims.getNotBefore().getTime());
|
||||
payload.setExp(claims.getExpiration().getTime());
|
||||
payload.setIat(claims.getIssuedAt().getTime());
|
||||
payload.setJti(claims.getId());
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
public boolean isInBlack(String jti) {
|
||||
return RedisUtil.exists(getBlackCacheKey(jti));
|
||||
}
|
||||
|
||||
public void logout(String token, String prv) throws JwtLogoutException {
|
||||
Claims claims = parseToken(token, prv);
|
||||
String cacheKey = getBlackCacheKey(claims.getId());
|
||||
Long expire = (claims.getExpiration().getTime() - System.currentTimeMillis()) / 1000;
|
||||
RedisUtil.set(cacheKey, 1, expire);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void userLogout(String token) throws JwtLogoutException {
|
||||
logout(token, SystemConstant.JWT_PRV_USER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void adminUserLogout(String token) throws JwtLogoutException {
|
||||
logout(token, SystemConstant.JWT_PRV_ADMIN_USER);
|
||||
}
|
||||
|
||||
private Claims parseToken(String token, String prv) throws JwtLogoutException {
|
||||
Claims claims =
|
||||
(Claims)
|
||||
Jwts.parserBuilder()
|
||||
.setSigningKey(getSecretKey())
|
||||
.require("prv", prv)
|
||||
.build()
|
||||
.parse(token)
|
||||
.getBody();
|
||||
if (isInBlack(claims.getId())) {
|
||||
throw new JwtLogoutException();
|
||||
}
|
||||
return claims;
|
||||
}
|
||||
|
||||
private SecretKey getSecretKey() {
|
||||
return Keys.hmacShaKeyFor(ConfigKey.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
private String getBlackCacheKey(String jti) {
|
||||
return ConfigCacheBlackPrefix + jti;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user