1、模拟用户登录
首先,用户进行了登录。登录成功之后,服务器记录了一个session,session存储的内容是用户的信息。
/**
* 登录接口
*/
@PostMapping(value = "/login")
public String login(UserLoginVO user, RedirectAttributes attributes, HttpSession session) {
// 1.远程调用登录
R r = memberFeignService.login(user);
if (r.getCode() == 0) {
// 2.登录成功,设置session值
MemberResponseVO data = r.getData(new TypeReference<MemberResponseVO>() {
});
session.setAttribute(AuthConstant.LOGIN_USER, data);
// 3.重定向,视图可以从session中拿到用户信息
return "redirect:http://gulimall.com:88";
} else {
// 4.登录失败,封装异常信息重定向返回
Map<String, String> errors = new HashMap<>();
errors.put("msg", r.getData("msg", new TypeReference<String>() {}));
attributes.addFlashAttribute("errors", errors);
return "redirect:http://auth.gulimall.com:88/login.html";
}
}
session.setAttribute(AuthConstant.LOGIN_USER, data);
MemberResponseVO.java
package com.pshdhx.common.vo.auth;
import lombok.Data;
import lombok.ToString;
import java.io.Serializable;
import java.util.Date;
@ToString
@Data
public class MemberResponseVO implements Serializable {
private static final long serialVersionUID = 5573669251256409786L;
private Long id;
/**
* 会员等级id
*/
private Long levelId;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 昵称
*/
private String nickname;
/**
* 手机号码
*/
private String mobile;
/**
* 邮箱
*/
private String email;
/**
* 头像
*/
private String header;
/**
* 性别
*/
private Integer gender;
/**
* 生日
*/
private Date birth;
/**
* 所在城市
*/
private String city;
/**
* 职业
*/
private String job;
/**
* 个性签名
*/
private String sign;
/**
* 用户来源
*/
private Integer sourceType;
/**
* 积分
*/
private Integer integration;
/**
* 成长值
*/
private Integer growth;
/**
* 启用状态
*/
private Integer status;
/**
* 注册时间
*/
private Date createTime;
/**
* 微博社交账户uid
*/
private String weiboUid;
/**
* 社交登录TOKEN
*/
private String accessToken;
/**
* 社交登录过期时间
*/
private long expiresIn;
}
2、模拟用户访问需要登录的接口
首选,该接口必须要被服务器进行拦截,判断使用该接口的用户是否登录过。所以需要配置拦截器。
配置拦截器步骤:
1、配置拦截器
package com.atguigu.gulimall.order.config;
import com.atguigu.common.constant.Auth.AuthConstant;
import com.atguigu.common.vo.auth.MemberResponseVO;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author pshdhx
* @date 2022-09-05 18:47
* @Des
* @Method
* @Summary
*/
@Component
public class LoginUserInterceptor implements HandlerInterceptor {
public static ThreadLocal<MemberResponseVO> loginUser = new ThreadLocal<>();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
MemberResponseVO attribute = (MemberResponseVO) request.getSession().getAttribute(AuthConstant.LOGIN_USER);
if(attribute != null){
loginUser.set(attribute);
return true;
}else{
//没有登录就去登录
request.getSession().setAttribute("msg","请先进行登录");
response.sendRedirect("http://auth.gulimall.com:88/login.html");
}
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
2、使拦截器在服务器生效
package com.atguigu.gulimall.order.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author pshdhx
* @date 2022-09-05 18:46
* @Des
* @Method
* @Summary
*/
@Configuration
public class OrderWebConfiguration implements WebMvcConfigurer {
@Autowired
private LoginUserInterceptor loginUserInterceptor;
/**
* 配置拦截器生效
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 访问任何订单请求需要拦截校验登录
registry.addInterceptor(loginUserInterceptor).addPathPatterns("/**");
}
}
结果:访问该服务的所有页面时, 都要经过拦截器,判断用户有没有登录。若用户登录,返回true,则能正常运行。如果用户没有登录,则重定向到登录页面。
3、使得session在整个服务范围内生效
用户在认证微服务模块登录成功,获取了session,那么如何在订单微服务模块进行生效呢?
所以需要设置session的生效范围。
这两个服务都配置如下代码:
package com.atguigu.gulimall.order.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
/**
* @author pshdhx
* @date 2022-09-06 8:38
* @Des
* springSession的配置,扩大作用域到整个域名
* @Method
* 需要导入包pom.xml
<!--整合springsession,实现session共享-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
* @Summary
*/
@Configuration
public class PshdhxSpringSessionConfig {
@Bean
public CookieSerializer cookieSerializer(){
DefaultCookieSerializer defaultCookieSerializer = new DefaultCookieSerializer();
defaultCookieSerializer.setDomainName("gulimall.com"); //放大作用域 ?? 如果端口不在会怎么样
defaultCookieSerializer.setCookieName("GULISESSION");
defaultCookieSerializer.setCookieMaxAge(60*60*24*7); //指定cookie的有效期为7天,关闭浏览器cookie即失效
return defaultCookieSerializer;
}
}
4、配置feign的请求头
feign远程调用时,是重新构建request请求,会丢失从浏览器访问的带来的cookie,所以需要给新的request请求添加cookie,如此,才有权限访问其他微服务的接口
package com.atguigu.gulimall.order.config;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
* @author pshdhx
* @date 2022-09-06 8:30
* @Des
* feign远程调用时,是重新构建request请求,会丢失从浏览器访问的带来的cookie,所以需要给新的request请求添加cookie
* @Method
*
* @Summary
*/
@Configuration
public class PshdhxFeignConfig {
@Bean("requestInterceptor")
public RequestInterceptor requestInterceptor(){
//创建拦截器
return new RequestInterceptor() {
@Override
public void apply(RequestTemplate requestTemplate) {
System.out.println("feign远程调用,拦截器封装请求头,给header添加cookie");
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if(requestAttributes != null){
HttpServletRequest request = requestAttributes.getRequest();
if(request != null){
//Cookie[] cookies = request.getCookies();
String cookie = request.getHeader("cookie");
requestTemplate.header("Cookie",cookie);
}
}
}
};
}
}