![](https://i-blog.csdnimg.cn/blog_migrate/6c61acd7bb11eafdd5f764aea1c68e0a.png)
<?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/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>shop</artifactId>
<groupId>com.yjxxt</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>shop-sso</artifactId>
<name>shop-sso</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- shop common 依赖 -->
<dependency>
<groupId>com.yjxxt</groupId>
<artifactId>shop-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- mybatis 依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- mysql 数据库依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid 连接池依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!-- spring data redis 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- commons-pool2 对象池依赖 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- dubbo依赖 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!--zkClient依赖-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
</dependencies>
<build>
</build>
</project>
spring:
profiles:
active: dev
server:
port: 9084
servlet:
context-path: /shop-sso
# Spring
spring:
# 数据源
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: root
# 指定 druid 连接池以及 druid 连接池配置
type: com.alibaba.druid.pool.DruidDataSource
druid:
initial-size: 1 # 初始连接数
max-active: 20 # 最大连接数
max-idle: 20 # 最大空闲
min-idle: 1 # 最小空闲
max-wait: 60000 # 最长等待时间
# redis 缓存
redis:
timeout: 10000 # 连接超时时间
host: 192.168.18.100 # Redis服务器地址
port: 6379 # Redis服务器端口
password: root
database: 0 # 选择哪个库,默认0库
lettuce:
pool:
max-active: 1024 # 最大连接数,默认 8
max-wait: 10000 # 最大连接阻塞等待时间,单位毫秒,默认 -1
max-idle: 200 # 最大空闲连接,默认 8
min-idle: 5 # 最小空闲连接,默认 0
# Dubbo
dubbo:
# 提供方应用信息,用于计算依赖关系
application:
name: shop-sso
# 使用 zookeeper 注册中心暴露服务地址
registry:
address: zookeeper://192.168.18.100:2181
# 用 dubbo 协议在 20880 端口暴露服务
protocol:
name: dubbo
port: 20883
# 扫描需要暴露的服务接口包
scan:
base-packages: com.yjxxt.sso.service
# MyBatis
mybatis:
# 配置 MyBatis数据返回类型别名(默认别名是类名)
type-aliases-package: com.yjxxt.sso.pojo
# 配置 MyBatis Mapper 映射文件
mapper-locations: classpath:mapper/*.xml
# Mybatis SQL 打印(方法接口所在的包,不是 Mapper.xml 所在的包)
logging:
level:
com.yjxxt.sso.mapper: debug
# Redis Key
#用户票据key
user.ticket: user:userTicket
package com.yjxxt.sso;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.yjxxt.sso.mapper")
public class ShopSSOApplication {
public static void main(String[] args) {
SpringApplication.run(ShopSSOApplication.class,args);
}
}
package com.yjxxt.sso.service;
import com.yjxxt.sso.pojo.Admin;
public interface ISSOService {
/**
* 登录方法
* @param userName 用户名
* @param password 密码
* @return
*/
public String login(String userName,String password);
/**
* 用户票据校验
* @param ticket
* @return
*/
public Admin validateTicket(String ticket);
/**
* 用户退出
* @param ticket
*/
public void logout(String ticket);
}
package com.yjxxt.sso.service.impl;
import com.yjxxt.common.utils.Md5Util;
import com.yjxxt.common.utils.UUIDUtil;
import com.yjxxt.sso.mapper.AdminMapper;
import com.yjxxt.sso.pojo.Admin;
import com.yjxxt.sso.pojo.AdminExample;
import com.yjxxt.sso.service.ISSOService;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Service(version = "1.0")
public class SSOServiceImpl implements ISSOService {
@Resource
private AdminMapper adminMapper;
@Resource(name="redisTemplate")
private RedisTemplate<String,Object> redisTemplate;
@Resource(name = "redisTemplate")
private ValueOperations<String,Object> valueOperations;
@Value("${user.ticket}")
private String userTicket;
@Override
public String login(String userName, String password) {
checkLoginParams(userName,password);
AdminExample example=new AdminExample();
example.createCriteria().andUserNameEqualTo(userName);
// 查询用户记录是否存在
List<Admin> userList= adminMapper.selectByExample(example);
if(CollectionUtils.isEmpty(userList)){
throw new RuntimeException("用户记录不存在!");
}
Admin admin = userList.get(0);
// 比对密码
password = Md5Util.getMd5WithSalt(password,admin.getEcSalt());
if(!(password.equals(admin.getPassword()))){
throw new RuntimeException("用户密码错误!");
}
// 用户登录成功 生成用户票据
String ticket = UUIDUtil.getUUID();
// 将用户信息存入redis 缓存 30分钟有效
valueOperations.set(userTicket+":"+ticket,admin,30, TimeUnit.MINUTES);
return ticket;
}
private void checkLoginParams(String userName, String password) {
if(StringUtils.isBlank(userName)){
throw new RuntimeException("用户名不能为空!");
}
if(StringUtils.isBlank(password)){
throw new RuntimeException("密码不能为空!");
}
}
@Override
public Admin validateTicket(String ticket) {
if(StringUtils.isBlank(ticket)){
//throw new RuntimeException("票据非法!");
System.out.println("票据非法!");
return null;
}
String cacheKey = userTicket+":"+ticket;
if(!redisTemplate.hasKey(cacheKey)){
//throw new RuntimeException("用户未登录或用户信息已过期");
System.out.println("用户未登录或用户信息已过期!");
return null;
}
return (Admin) valueOperations.get(cacheKey);
}
@Override
public void logout(String ticket) {
String cacheKey = userTicket+":"+ticket;
if(redisTemplate.hasKey(cacheKey)){
redisTemplate.delete(cacheKey);
}
}
}
package com.yjxxt.common.utils;
import java.util.UUID;
/**
* 生成UUID工具类
*/
public class UUIDUtil {
public static String getUUID() {
return UUID.randomUUID().toString().replace("-", "");
}
public static void main(String[] args) {
System.out.println(getUUID());
}
}
package com.yjxxt.common.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* @see(功能介绍) : 加密工具类
* @version(版本号) : 1.0
* @since : JDK 1.8
*/
public class Md5Util {
// 全局数组
private final static String[] strDigits = {"0", "1", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "2", "3", "4"};
// 返回形式为数字跟字符串
private static String byteToArrayString(byte bByte) {
int iRet = bByte;
// System.out.println("iRet="+iRet);
if (iRet < 0) {
iRet += 256;
}
int iD1 = iRet / 16;
int iD2 = iRet % 16;
return strDigits[iD1] + strDigits[iD2];
}
// 返回形式只为数字
private static String byteToNum(byte bByte) {
int iRet = bByte;
System.out.println("iRet1=" + iRet);
if (iRet < 0) {
iRet += 256;
}
return String.valueOf(iRet);
}
// 转换字节数组为16进制字串
private static String byteToString(byte[] bByte) {
StringBuffer sBuffer = new StringBuffer();
for (int i = 0; i < bByte.length; i++) {
sBuffer.append(byteToArrayString(bByte[i]));
}
return sBuffer.toString();
}
// 根据salt生成md5值
public static String getMd5WithSalt(String originStr, String salt) {
// 三元表达式
salt = salt == null ? "" : salt;
String resultString = null;
try {
// 创建MD5算法的MessageDigest实例对象
MessageDigest md = MessageDigest.getInstance("MD5");
// md.digest()该函数返回值为存放哈希值结果的byte数组
resultString = byteToString(md.digest((originStr + salt).getBytes()));
} catch (NoSuchAlgorithmException ex) {
ex.printStackTrace();
}
return resultString;
}
public static void main(String[] args) {
String result = getMd5WithSalt("123456", "a2ck");
System.out.println(result);
}
}
package com.yjxxt.common.result;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
/**
* @see(功能介绍) : Cookie工具类
* @version(版本号) : 1.0
* @since : JDK 1.8
*/
public final class CookieUtil {
/**
* 得到Cookie的值, 不编码
*
* @param request
* @param cookieName
* @return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName) {
return getCookieValue(request, cookieName, false);
}
/**
* 得到Cookie的值,
*
* @param request
* @param cookieName
* @return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName, boolean isDecoder) {
Cookie[] cookieList = request.getCookies();
if (cookieList == null || cookieName == null) {
return null;
}
String retValue = null;
try {
for (int i = 0; i < cookieList.length; i++) {
if (cookieList[i].getName().equals(cookieName)) {
if (isDecoder) {
retValue = URLDecoder.decode(cookieList[i].getValue(), "UTF-8");
} else {
retValue = cookieList[i].getValue();
}
break;
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return retValue;
}
/**
* 得到Cookie的值,
*
* @param request
* @param cookieName
* @return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName, String encodeString) {
Cookie[] cookieList = request.getCookies();
if (cookieList == null || cookieName == null) {
return null;
}
String retValue = null;
try {
for (int i = 0; i < cookieList.length; i++) {
if (cookieList[i].getName().equals(cookieName)) {
retValue = URLDecoder.decode(cookieList[i].getValue(), encodeString);
break;
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return retValue;
}
/**
* 设置Cookie的值 不设置生效时间默认浏览器关闭即失效,也不编码
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue) {
setCookie(request, response, cookieName, cookieValue, -1);
}
/**
* 设置Cookie的值 在指定时间内生效,但不编码
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, int cookieMaxage) {
setCookie(request, response, cookieName, cookieValue, cookieMaxage, false);
}
/**
* 设置Cookie的值 不设置生效时间,但编码
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, boolean isEncode) {
setCookie(request, response, cookieName, cookieValue, -1, isEncode);
}
/**
* 设置Cookie的值 在指定时间内生效, 编码参数
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, int cookieMaxage, boolean isEncode) {
doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, isEncode);
}
/**
* 设置Cookie的值 在指定时间内生效, 编码参数(指定编码)
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, int cookieMaxage, String encodeString) {
doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, encodeString);
}
/**
* 删除Cookie带cookie域名
*/
public static void deleteCookie(HttpServletRequest request, HttpServletResponse response,
String cookieName) {
doSetCookie(request, response, cookieName, "", -1, false);
}
/**
* 设置Cookie的值,并使其在指定时间内生效
*
* @param cookieMaxage cookie生效的最大秒数
*/
private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) {
try {
if (cookieValue == null) {
cookieValue = "";
} else if (isEncode) {
cookieValue = URLEncoder.encode(cookieValue, "utf-8");
}
Cookie cookie = new Cookie(cookieName, cookieValue);
if (cookieMaxage > 0)
cookie.setMaxAge(cookieMaxage);
if (null != request) {// 设置域名的cookie
String domainName = getDomainName(request);
System.out.println(domainName);
if (!"localhost".equals(domainName)) {
cookie.setDomain(domainName);
}
}
cookie.setPath("/");
response.addCookie(cookie);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 设置Cookie的值,并使其在指定时间内生效
*
* @param cookieMaxage cookie生效的最大秒数
*/
private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
String cookieName, String cookieValue, int cookieMaxage, String encodeString) {
try {
if (cookieValue == null) {
cookieValue = "";
} else {
cookieValue = URLEncoder.encode(cookieValue, encodeString);
}
Cookie cookie = new Cookie(cookieName, cookieValue);
if (cookieMaxage > 0) {
cookie.setMaxAge(cookieMaxage);
}
if (null != request) {// 设置域名的cookie
String domainName = getDomainName(request);
System.out.println(domainName);
if (!"localhost".equals(domainName)) {
cookie.setDomain(domainName);
}
}
cookie.setPath("/");
response.addCookie(cookie);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 得到cookie的域名
*/
private static final String getDomainName(HttpServletRequest request) {
String domainName = null;
// 通过request对象获取访问的url地址
String serverName = request.getRequestURL().toString();
if (serverName == null || serverName.equals("")) {
domainName = "";
} else {
// 将url地下转换为小写
serverName = serverName.toLowerCase();
// 如果url地址是以http://开头 将http://截取
if (serverName.startsWith("http://")) {
serverName = serverName.substring(7);
}
int end = serverName.length();
// 判断url地址是否包含"/"
if (serverName.contains("/")) {
//得到第一个"/"出现的位置
end = serverName.indexOf("/");
}
// 截取
serverName = serverName.substring(0, end);
// 根据"."进行分割
final String[] domains = serverName.split("\\.");
int len = domains.length;
if (len > 3) {
// www.xxx.com.cn
domainName = domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1];
} else if (len <= 3 && len > 1) {
// xxx.com or xxx.cn
domainName = domains[len - 2] + "." + domains[len - 1];
} else {
domainName = serverName;
}
}
if (domainName != null && domainName.indexOf(":") > 0) {
String[] ary = domainName.split("\\:");
domainName = ary[0];
}
return domainName;
}
}
<?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/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>shop</artifactId>
<groupId>com.yjxxt</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>shop-sso</artifactId>
<name>shop-sso</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- shop common 依赖 -->
<dependency>
<groupId>com.yjxxt</groupId>
<artifactId>shop-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- mybatis 依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- mysql 数据库依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid 连接池依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!-- spring data redis 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- commons-pool2 对象池依赖 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- dubbo依赖 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!--zkClient依赖-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
</dependencies>
<build>
</build>
</project>
shop-manager的application-dev.yml
<?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/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>shop</artifactId>
<groupId>com.yjxxt</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>shop-manager</artifactId>
<name>shop-manager</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- shop common 依赖 -->
<dependency>
<groupId>com.yjxxt</groupId>
<artifactId>shop-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- spring boot freemarker 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- mybatis 依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- mysql 数据库依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid 连接池依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!-- spring boot test 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--七牛云SKD-->
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- spring data redis 组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- commons-pool2 对象池依赖 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>com.yjxxt</groupId>
<artifactId>shop-rpc</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- dubbo依赖 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!--zkClient依赖-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.yjxxt</groupId>
<artifactId>shop-sso</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- google kaptcha验证码 -->
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>kaptcha</artifactId>
</dependency>
</dependencies>
<build>
</build>
</project>
2.6.2shop-manager:ShopManagerApplication
package com.yjxxt.manager;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.yjxxt.manager.mapper")
public class ShopManagerApplication {
public static void main(String[] args) {
SpringApplication.run(ShopManagerApplication.class,args);
}
}
package com.yjxxt.manager.service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface ICookieService {
/**
* 设置cookie
* @param request
* @param response
* @param ticket
* @return
*/
void setCookie(HttpServletRequest request, HttpServletResponse response, String ticket);
}
package com.yjxxt.manager.service.impl;
import com.yjxxt.common.result.CookieUtil;
import com.yjxxt.manager.service.ICookieService;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Service
public class CookieServiceImpl implements ICookieService {
@Override
public void setCookie(HttpServletRequest request, HttpServletResponse response, String ticket) {
CookieUtil.setCookie(request,response,"userTicket",ticket);
}
}
package com.yjxxt.manager.controller;
import com.yjxxt.common.enums.BaseResultEnum;
import com.yjxxt.common.result.BaseResult;
import com.yjxxt.common.result.CookieUtil;
import com.yjxxt.manager.service.ICookieService;
import com.yjxxt.sso.service.ISSOService;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
@RequestMapping("user")
public class UserController {
@Reference(version = "1.0")
private ISSOService ssoService;
@Resource
private ICookieService cookieService;
@RequestMapping("login")
@ResponseBody
public BaseResult login(String userName, String password, String verify,
HttpServletRequest request, HttpServletResponse response){
try {
//获取验证码
String capText = (String) request.getSession().getAttribute("pictureVerifyKey");
BaseResult baseResult = new BaseResult();
//验证码是否一致,不一致返回提示信息
if (null==verify|| null ==capText || StringUtils.isEmpty(verify.trim()) || !verify.trim().equals(capText)) {
baseResult.setCode(BaseResultEnum.PASS_ERROR_03.getCode());
baseResult.setMessage(BaseResultEnum.PASS_ERROR_03.getMessage());
return baseResult;
}
String ticket= ssoService.login(userName,password);
// 将票据信息写入浏览器
cookieService.setCookie(request,response,ticket);
return BaseResult.success();
} catch (Exception e) {
e.printStackTrace();
return BaseResult.error(e.getMessage());
}
}
@RequestMapping("logout")
public String logout(HttpServletRequest request,HttpServletResponse response){
String ticket = CookieUtil.getCookieValue(request,"userTicket");
ssoService.logout(ticket);
CookieUtil.deleteCookie(request,response,"userTicket");
return "redirect:"+request.getContextPath()+"/login";
}
}
package com.yjxxt.manager.interceptors;
import com.yjxxt.common.result.CookieUtil;
import com.yjxxt.sso.pojo.Admin;
import com.yjxxt.sso.service.ISSOService;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;
public class LoginInterceptor implements HandlerInterceptor {
@Reference(version = "1.0")
private ISSOService ssoService;
@Resource(name = "redisTemplate")
private ValueOperations<String,Object> valueOperations;
@Value("${user.ticket}")
private String userTicket;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
/*
1.获取cookie 中用户票据
2.判断票据是否存在
不存在 用户未登录 跳转到登录页面
存在 获取用户信息存入session 放行
*/
String ticket= CookieUtil.getCookieValue(request,"userTicket");
Admin admin= ssoService.validateTicket(ticket);
if(null ==admin){
response.sendRedirect(request.getContextPath()+"/login");
return false;
}
// 重新存入用户信息到redis 30分钟内有效
valueOperations.set(userTicket+":"+ticket,admin,30, TimeUnit.MINUTES);
request.getSession().setAttribute("user",admin);
return true;
}
}
package com.yjxxt.manager.config;
import com.yjxxt.manager.interceptors.LoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
@Configuration
public class ManagerConfig extends WebMvcConfigurerAdapter {
/*
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/bootstrap/**").addResourceLocations("classpath:/bootstrap/");
registry.addResourceHandler("/css/**").addResourceLocations("classpath:/bootstrap/");
registry.addResourceHandler("/dist/**").addResourceLocations("classpath:/bootstrap/");
registry.addResourceHandler("/bootstrap/**").addResourceLocations("classpath:/bootstrap/");
}*/
@Bean
public LoginInterceptor loginInterceptor(){
return new LoginInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/bootstrap/**",
"/css/**","/dist/**","/images/**",
"/img/**","js/**","/plugins/**")
.excludePathPatterns("/login")
.excludePathPatterns("/image/**")
.excludePathPatterns("/user/login")
.excludePathPatterns("/user/logout");
}
}
<div class="form-group">
<button type="button" class="btn btn-primary btn-block btn-flat"
onclick="userLogin()">立即登陆</button>
</div>
//用户登录
function userLogin() {
$.ajax({
url: "${ctx}/user/login",
type: "POST",
data: {
userName: $("#username").val(),
password: $("#password").val()
},
dataType: "JSON",
success: function (result) {
if (200 == result.code) {
location.href = "${ctx}/index";
} else {
layer.alert("用户名或密码错误,请重新输入!");
}
},
error: function () {
layer.alert("亲,系统正在升级中,请稍后再试!");
}
});
}