web页面拦截用户登录,管理session和cookie

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);

                    }
                }
            }
        };
    }
    
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CookieSession和Storage都是用于在Web应用程序中存储数据的方法,它们的主要区别在于数据存储的位置、作用域和使用方式。 Cookie是存储在客户端的一小段文本信息,它的作用是跟踪用户的会话状态,例如用户的登录状态,以及存储一些用户个性化的设置。Cookie的缺点是容易被拦截和篡改,因此敏感信息不应该存储在Cookie中。 Session是存储在服务器端的会话状态信息,它的作用也是为了跟踪用户的会话状态。当用户第一次访问应用程序时,服务器会创建一个唯一的Session ID,并将该ID存储在Cookie中,当用户再次访问应用程序时,服务器通过Session ID来识别用户,并从服务器中查找与该Session ID对应的Session数据,从而恢复用户的会话状态。 Storage分为localStorage和sessionStorage两种,它们都是HTML5提供的新特性,用于在客户端存储数据,与Cookie不同的是,它们不会随着HTTP请求被发送到服务器端。localStorage和sessionStorage的主要区别在于数据的作用域和生命周期。localStorage存储的数据在同一浏览器、同一域名下都可以共享,而sessionStorage存储的数据只在当前会话中有效,当用户关闭浏览器或者标签页时,sessionStorage中的数据就会被清除。 总体来说,CookieSession和Storage的主要区别在于数据存储的位置、作用域和使用方式。根据具体的需求,我们可以选择不同的存储方式来实现数据的存储和传递。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值