@H_404_1@简介
创建三个服务:
大体思路:每个服务都设置一个拦截器检查cookie中是否有token,若有token,则放行,若没有token,重定向到统一认证中心服务进行登录,登录成功后返回到被拦截的服务。
@H_404_1@搭建redis集群服务
搭建redis集群参考文档
@H_404_1@搭建统一认证中心
- /**
- * 单点登录既要注册到服务注册中心,又要向redis服务系统获取鼓舞
- * 所以要添加 @EnableDiscoveryClient @EnableEurekaClient 两个注解
- *
- */
- @EnableDiscoveryClient
- @EnableEurekaClient
- @EnableFeignClients
- @MapperScan(basePackages = "com.example.itokenservicesso.mapper")
- @SpringBootApplication
- public class ItokenServiceSsoApplication {
- public static void main(String[] args) {
- SpringApplication.run(ItokenServiceSsoApplication.class,args);
- }
- }
@H_404_1@消费redis服务和熔断器
- @FeignClient(value = "itoken-service-redis",fallback = RedisServiceFallBack.class)
- public interface RedisService {
- @PostMapping(value = "put")
- public String put(@RequestParam(value = "key") String key,@RequestParam(value = "value") String value,@RequestParam(value = "seconds") long seconds);
- @GetMapping(value = "get")
- public String get(@RequestParam(value = "key") String key);
- }
- @Component
- public class RedisServiceFallBack implements RedisService {
- @Override
- public String put(String key,String value,long seconds) {
- return FallBack.badGateWay();
- }
- @Override
- public String get(String key) {
- return FallBack.badGateWay();
- }
- }
- @Service
- public class LoginServiceImpl implements LoginService {
- @Autowired
- private UserMapper userMapper;
- @Autowired
- private RedisService redisService;
- @Override
- public User login(String loginCode,String plantPassword) {
- //从缓存中获取登录用户的数据
- String json = redisService.get(loginCode);
- User user = null;
- //如果缓存中没有数据,从数据库取数据
- if (json == null) {
- user = userMapper.selectAll(loginCode);
- String passwordMd5 = DigestUtils.md5DigestAsHex(plantPassword.getBytes());
- if (user != null && passwordMd5.equals(user.getPassword())) {
- //登录成功,刷新缓存
- try {
- redisService.put(loginCode,JsonUtil.objectToString(user),60 * 60 * 24);
- } catch (JsonProcessingException e) {
- e.printStackTrace();
- }
- return user;
- } else {
- return null;
- }
- }
- //如果缓存中有数据
- else {
- try {
- user = JsonUtil.stringToObject(json,User.class);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return user;
- }
- }
@H_404_1@contoller层,处理登录业务和登录跳转
- /**
- * 登录业务
- *
- * @param loginCode
- * @param password
- * @return
- */
- @PostMapping("login")
- public String login(String loginCode,String password,@RequestParam(required = false) String url,HttpServletRequest request,HttpServletResponse response,RedirectAttributes redirectAttributes) {
- User user = loginService.login(loginCode,password);
- //登录成功
- if (user != null) {
- String token = UUID.randomUUID().toString();
- //将token放入缓存
- String result = redisService.put(token,loginCode,60 * 60 * 24);
- //如果redisService没有熔断,也就是返回ok,才能执行
- if (result != null && result.equals("ok")) {
- CookieUtil.setCookie(response,"token",token,60 * 60 * 24);
- if (url != null && !url.trim().equals(""))
- return "redirect:" + url;
- }
- //熔断后返回错误提示
- else {
- redirectAttributes.addFlashAttribute("message","服务器异常");
- }
- }
- //登录失败
- else {
- redirectAttributes.addFlashAttribute("message","用户名或密码错误");
- }
- return "redirect:/login";
- }
- @Autowired
- private LoginService loginService;
- @Autowired
- private RedisService redisService;
- /**
- * 跳转登录页
- */
- @GetMapping("login")
- public String login(HttpServletRequest request,Model model,@RequestParam(required = false) String url
- ) {
- String token = CookieUtil.getCookie(request,"token");
- //token不为空可能已登录,从redis获取账号
- if (token != null && token.trim().length() != 0) {
- String loginCode = redisService.get(token);
- //如果账号不为空,从redis获取该账号的个人信息
- if (loginCode != null && loginCode.trim().length() != 0) {
- String json = redisService.get(loginCode);
- if (json != null && json.trim().length() != 0) {
- try {
- User user = JsonUtil.stringToObject(json,User.class);
- //已登录
- if (user != null) {
- if (url != null && url.trim().length() != 0) {
- return "redirect:" + url;
- }
- }
- //将登录信息传到登录页
- model.addAttribute("user",user);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- return "login";
- }
@H_404_1@搭建服务消费者:添加一个拦截器,判断token是否为空
- public class WebAdminInterceptor implements HandlerInterceptor {
- @Autowired
- private RedisService redisService;
- @Override
- public boolean preHandle(HttpServletRequest request,Object handler) throws Exception {
- String token = CookieUtil.getCookie(request,"token");
- //token为空,一定没有登录
- if (token == null || token.isEmpty()) {
- response.sendRedirect("http://localhost:8503/login?url=http://localhost:8601/login");
- return false;
- }
- return true;
- }
- @Override
- public void postHandle(HttpServletRequest request,Object handler,ModelAndView modelAndView) throws Exception {
- HttpSession session = request.getSession();
- User user = (User) session.getAttribute("user");
- //已登陆状态
- if (user != null) {
- if (modelAndView != null) {
- modelAndView.addObject("user",user);
- }
- }
- //未登录状态
- else {
- String token = CookieUtil.getCookie(request,"token");
- if (token != null && !token.isEmpty()) {
- String loginCode = redisService.get(token);
- if (loginCode != null && !loginCode.isEmpty()) {
- String json = redisService.get(loginCode);
- if (json != null && !json.isEmpty()) {
- //已登录状态,创建局部会话
- user = JsonUtil.stringToObject(json,User.class);
- if (modelAndView != null) {
- modelAndView.addObject("user",user);
- }
- request.getSession().setAttribute("user",user);
- }
- }
- }
- }
- //二次确认是否有用户信息
- if (user == null) {
- response.sendRedirect("http://localhost:8503/login?url=http://localhost:8601/login");
- }
- }
- @Override
- public void afterCompletion(HttpServletRequest request,Exception ex) throws Exception {
- }
- }
- @Configuration
- public class WebAdminInterceptorConfig implements WebMvcConfigurer {
- //将拦截器设置为Bean,在拦截其中才能使用@AutoWired注解自动注入
- @Bean
- WebAdminInterceptor webAdminInterceptor() {
- return new WebAdminInterceptor();
- }
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- registry.addInterceptor(webAdminInterceptor())
- .addPathPatterns("/**")
- .excludePathPatterns("/static");
- }
- }
- @RequestMapping(value = {"/login"})
- public String index(){
- return "index";
- }