[SpringBoot16] SpringBoot で Cookie を使用してログインを記憶する

ログインのたびにパスワードを入力するのは非常に面倒です。ログイン状態を記憶する機能を実装するために、この機能を実現するために Cookie を使用しています。

1. クッキーの紹介 

ユーザーのローカル端末に保存される一種のデータである Cookie は、複数形の Cookie を使用することもあります。タイプは「小さなテキスト ファイル」です。これは、ユーザーの身元を特定し、セッションを追跡するために、一部の Web サイトによってユーザーのローカル端末に保存されるデータ (通常は暗号化されます) であり、情報はユーザーのクライアントによって一時的または永続的に保存されます。コンピューター。

実際、Cookie はキーと値で構成され、サーバーからの応答と共にクライアント ブラウザーに送信されます。次に、クライアント ブラウザは Cookie を保存し、次にサーバーにアクセスしたときにその Cookie をサーバーに送信します。
 

1. Cookie は HTTP プロトコルの仕様の 1 つで、サーバーとクライアントの間で送受信される小さなデータです
2. まず、サーバーが応答ヘッダーを介してクライアントに Cookie を送信し、クライアントが Cookie を保存します。
3. クライアントが同じサーバーに再度リクエストするとき、クライアントは、サーバーが保存した Cookie をリクエスト ヘッダーに追加してサーバーに送信します. 4. Cookie は、サーバーがクライアントに保存したデータです.
5
. Cookie はキーと値のペアです
クッキーダイアグラム

 

2. クッキーの使用 

1. クッキーを作成する 

 // Cookie はキーと値のペアのデータ形式
Cookie cookie_username = new Cookie("cookie_username", username);

 2. Cookie の有効期間を設定する

// つまり、有効期限、単位は秒 (秒)
cookie_username.setMaxAge(30 * 24 * 60 * 60); 

3. Cookie 共有パスを設定する 

// この Cookie が現在のプロジェクトの下で保持されていることを示します
cookie_username.setPath(request.getContextPath()); 

4. Cookie をクライアントに送信する 

// HttpServletResponse オブジェクトを使用して Cookie をクライアントに送信する
response.addCookie(cookie_username); 

5. Cookie を破棄する 

// キー Cookie に従って値を空にします
cookie_username = new Cookie("cookie_username", "");
// 持続時間を 0 に設定します
cookie_username.setMaxAge(0);
// 共有パスを設定します
cookie_username.setPath(request. getContextPath() );
// Cookie をクライアントに送信する
response.addCookie(cookie_username); 

3. トピックを入力してください 

以上で、Cookie とは何か、Cookie の作成と破棄の方法を理解できました.次に、Cookie を使用してログイン状態を記憶する機能を実現します.プロジェクト全体は SpringBoot に基づいて実装されています. 

1.インターセプターを登録する 

/**
* 注册拦截器
*/
@Configuration
public class WebConfigurer implements WebMvcConfigurer {

    @Autowired
    private LoginInterceptor loginHandlerInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        InterceptorRegistration ir = registry.addInterceptor(loginHandlerInterceptor);
        // 拦截路径
        ir.addPathPatterns("/*");
        // 不拦截路径
        List<String> irs = new ArrayList<String>();
        irs.add("/api/*");
        irs.add("/wechat/*");
        irs.add("/oauth");
        ir.excludePathPatterns(irs);
    }
}

 すべてのリクエスト パスを傍受し、api や wechat などのリクエスト パスを手放しました

ここで質問があるかもしれません。ログイン インターフェースをリクエストするための API リクエスト パスを手放さない理由は、ログイン インターフェースをリクエストするときにログイン リクエストをインターセプトするためです。ログイン インターフェイスに入るには、メイン インターフェイスに直接移動します

カスタムのログイン インターセプター: LoginInterceptor を使用します. 2 番目のステップでは、実装原理を詳細に説明します.
2. ログイン インターセプト

/**
* 未登录拦截器
*/
@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private LoginDao dao;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获得cookie
        Cookie[] cookies = request.getCookies();
        // 没有cookie信息,则重定向到登录界面
        if (null == cookies) {
            response.sendRedirect(request.getContextPath() + "/login");
            return false;
        }
        // 定义cookie_username,用户的一些登录信息,例如:用户名,密码等
        String cookie_username = null;
        // 获取cookie里面的一些用户信息
        for (Cookie item : cookies) {
            if ("cookie_username".equals(item.getName())) {
                cookie_username = item.getValue();
                break;
            }
        }
        // 如果cookie里面没有包含用户的一些登录信息,则重定向到登录界面
        if (StringUtils.isEmpty(cookie_username)) {
            response.sendRedirect(request.getContextPath() + "/login");
            return false;
        }
        // 获取HttpSession对象
        HttpSession session = request.getSession();
        // 获取我们登录后存在session中的用户信息,如果为空,表示session已经过期
        Object obj = session.getAttribute(Const.SYSTEM_USER_SESSION);
        if (null == obj) {
			// 根据用户登录账号获取数据库中的用户信息
        	UserInfo dbUser = dao.getUserInfoByAccount(cookie_username);
            // 将用户保存到session中
            session.setAttribute(Const.SYSTEM_USER_SESSION, dbUser);
        }
        // 已经登录
        return true;
    }
}

 3. ログイン要求

制御層

/**
  * 执行登录
  */
 @PostMapping("login")
 @ResponseBody
 public String login(String username, String password, HttpSession session, HttpServletRequest request, HttpServletResponse response) {
     return service.doLogin(username.trim(), password.trim(), session, request, response).toJSONString();
 }

ビジネス層

/**
 * 执行登录
 */
public JSONObject doLogin(String username, String password, HttpSession session, HttpServletRequest request, HttpServletResponse response) {
	// 最终返回的对象
    JSONObject res = new JSONObject();
    res.put("code", 0);
    if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
        res.put("msg", "请输入手机号或密码");
        return res;
    }
    UserInfo dbUser = dao.getUserInfoByAccount(username);
    if (null == dbUser) {
        res.put("msg", "该账号不存在,请检查后重试");
        return res;
    }
    // 验证密码是否正确
    String newPassword = PasswordUtils.getMd5(password, username, dbUser.getSalt());
    if (!newPassword.equals(dbUser.getPassword())) {
        res.put("msg", "手机号或密码错误,请检查后重试");
        return res;
    }
    // 判断账户状态
    if (1 != dbUser.getStatus()) {
        res.put("msg", "该账号已被冻结,请联系管理员");
        return res;
    }
    // 将登录用户信息保存到session中
    session.setAttribute(Const.SYSTEM_USER_SESSION, dbUser);
    // 保存cookie,实现自动登录
    Cookie cookie_username = new Cookie("cookie_username", username);
    // 设置cookie的持久化时间,30天
    cookie_username.setMaxAge(30 * 24 * 60 * 60);
    // 设置为当前项目下都携带这个cookie
    cookie_username.setPath(request.getContextPath());
    // 向客户端发送cookie
    response.addCookie(cookie_username);
    res.put("code", 1);
    res.put("msg", "登录成功");
    return res;
}

4.ログアウトとログイン

/**
 * 退出登录
 */
@RequestMapping(value = "logout")
public String logout(HttpSession session, HttpServletRequest request, HttpServletResponse response) {
    // 删除session里面的用户信息
    session.removeAttribute(Const.SYSTEM_USER_SESSION);
    // 保存cookie,实现自动登录
    Cookie cookie_username = new Cookie("cookie_username", "");
    // 设置cookie的持久化时间,0
    cookie_username.setMaxAge(0);
    // 设置为当前项目下都携带这个cookie
    cookie_username.setPath(request.getContextPath());
    // 向客户端发送cookie
    response.addCookie(cookie_username);
    return "login";
}

 ログアウト時には、セッション内のユーザー情報を削除し、Cookie 内のユーザー情報を削除してから、ログイン インターフェイスにリクエストする必要があります。

4.まとめ

上記は、SpringBoot で Cookie を使用してログインを記憶する機能を実現するもので、このプロジェクトでは比較的実用的な機能です。

おすすめ

転載: blog.csdn.net/wufaqidong1/article/details/129675560