网站登录的流程和逻辑

网站登录的流程和逻辑

01、图解

01、在templates新建一个login.html

同时把login.css的css/js/img放入到static目录下:
在这里插入图片描述

02、定义LoginController跳转login.html

package com.li.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;


@Controller
public class LoginController {

    @GetMapping("/login")
    public String login() {
        return "login";
    }
}

03、浏览器访问http://localhost:8888/login

在这里插入图片描述

02、登录逻辑交互

  • vue+axios异步的方式交互处理

01、打开login.html,引入vue/axios的js文件如下

  <script src="/js/vue.min.js"></script>
  <script src="/js/axios.min.js"></script>
  <script src="/js/login/login.js"></script>

02、定义login.js初始化vue实例

var vue = new Vue({
    el:"#app",
    data:{
        title:"MoMo登录"
    }
});

03、编写登录的具体触发事件

注意:在刚开始的时候,不要考虑什么验证,数据合法性等。这些东西一定要在开发完毕或者差不多的时候,在去考虑数据合法性。

一定先学会做核心功能
  • 获取用户输入的账号和密码=
  • 然后传递到后台
  • 通过账号查询你用户信息
  • 根据查询的用户信息的密码和你输入的密码进行匹配
  • 如果匹配成功,说明登录有效,并且把用户信息放入到session中进行记录。
  • 如果匹配是不,说明用户名和密码错误,给前端进行提示
  • 然后在考虑各种数据的安全性和有效性
  • 然后在考虑增加验证码或者验证码
  • 可以考虑使用短信登录
  • 在去考虑使用手机号码登录,昵称等,账号等等
  • 登录限制(黑白名单)

在login.js中定义登录按钮触发的事件:

var vue = new Vue({
    el:"#app",
    data:{
        title:"MoMo登录",
        user:{
            account:"",
            password:""
        }
    },
    methods:{
        toLogin:function(){
            var that = this;
            var user = that.user;
            alert(JSON.stringify(user))
        }
    }
});

一定测试打印

04、定义后台的处理接受参数的UserVo

package com.li;

import lombok.Data;

@Data
public class UserVo {
    
    // 账号
    private String account;
    // 密码
    private String password;
    // 验证码
    private String code;
    
}

具体的页面登录代码如下:

package com.li.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.li.UserVo;
import com.li.entity.User;
import com.li.service.user.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;


@Controller
public class LoginController {

    @Autowired
    private IUserService userService;

    @PostMapping("/logined")
    @ResponseBody
    public String logined(@RequestBody UserVo userVo, HttpSession session) {
        //1: 根据账号去查询用户信息
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getTelephone, userVo.getAccount());
        User user = userService.getOne(lambdaQueryWrapper);
        // 2: 如果用户存在直接抛异常
        if (user == null) {
            return "fail";
        }

        if (user.getPassword().equals(userVo.getPassword())) {
            session.setAttribute("sessionuser", user);
            return "success";
        }
        
        return "fail";
    }
}

前端js处理代码

var vue = new Vue({
    el:"#app",
    data:{
        title:"MoMo登录",
        user:{
            account:"10000",
            password:"123456",
            code:""
        }
    },
    methods:{
        toLogin:function(){
            var that = this;
            var user = that.user;
            
            axios.post("/logined",user).then(function(res){
                 if(res.data == "success"){
                     window.location.href = "/";
                 }else{
                     alert("输入账号密码有误");
                     document.getElementById("pwd").value = "";
                     document.getElementById("pwd").focus();
                 }
            })
        }
    }
});

这里就完成了登录逻辑。

  • 注意问题:现在使用axios的post处理业务,post传递给服务器端参数的时候,一定是要用对象,并且这个对象参数的前面一定要增加@RequestBody。

    @PostMapping("/logined")
    @ResponseBody
    public String logined(@RequestBody UserVo userVo);
    

    否则你拿不到,千万不要写如下代码

    @PostMapping("/logined")
    @ResponseBody
    public String logined(String account,String password);
    

    如果不明白看官网文档:http://www.axios-js.com/zh-cn/docs/

  • 注意问题2:请记住,当前的LoginController是一个@Controller. 这个注解类中既有登录页面的跳转,又有异步逻辑的处理,你的处理登录的逻辑请记住一定要加@ResponseBody注解。

05、改进代码 – 密码加密

在项目的包中新建一个utils包,放入pwd/MdUtil.java密码加密的工具类:

package com.li.utils.pwd;

import java.math.BigInteger;
import java.security.MessageDigest;

public class MD5Util {
    public MD5Util() {
    }

    public static String md5(String str) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            md5.update(str.getBytes("UTF-8"));
            return bytesToHex(md5.digest());
        } catch (Exception var2) {
            throw new RuntimeException(var2);
        }
    }

    public static String md5slat(String str){
        return MD5Util.md5(MD5Util.md5("li"+str+"202102170318!!!"));
    }

    public static String bytesToHex(byte[] bytes) {
        BigInteger bigInt = new BigInteger(1, bytes);

        String hashtext;
        for(hashtext = bigInt.toString(16); hashtext.length() < 32; hashtext = "0" + hashtext) {
        }

        return hashtext;
    }

    public static void main(String[] args) {

        System.out.println(md5slat("123456"));


    }
}

运行main函数,把生成的密码修改到数据中。然后开始去校验输入的密码是否和数据库加密一致,如下:

package com.li.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.li.UserVo;
import com.li.entity.User;
import com.li.service.user.IUserService;
import com.li.utils.pwd.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;


@Controller
public class LoginController {

    @Autowired
    private IUserService userService;

    /**
     * 跳页面
     *
     * @return
     */
    @GetMapping("/login")
    public String login() {
        return "login";
    }

    /**
     * 处理登录逻辑
     *
     * @param userVo
     * @param session
     * @return
     */
    @ResponseBody
    @PostMapping("/logined")
    public String logined(@RequestBody UserVo userVo, HttpSession session) {
        //1: 根据账号去查询用户信息
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getTelephone, userVo.getAccount());
        User user = userService.getOne(lambdaQueryWrapper);
        // 2: 如果用户存在直接抛异常
        if (user == null) {
            return "fail";
        }
        // 3:把用户输入的密码进行加密
        String inputpwd = MD5Util.md5slat(userVo.getPassword());
        // 4:然后把用户输入的密码进行加密和数据库已经加密的密码进行比较,如果一致,就说明是正确的。
        if (user.getPassword().equals(inputpwd)) {
            // 5: 正确的话,就把登录的用户信息放到session中。
            session.setAttribute("sessionuser", user);
            return "success";
        }

        // 6:不一致用户密码不存在
        return "fail";
    }
}

06、改进代码–登录以后不能在登录

  • 如果一个用户已经登录,如果在进入登录页面,直接进入首页

    /**
     * 跳页面
     *
     * @return
     */
    @GetMapping("/login")
    public String login(HttpSession session) {
        // 1:获取用户登录的信息
        User user = (User)session.getAttribute(KConstants.SESSION_USER);
        // 2:如果已经登录
        if(user!=null){
            // 3:直接服务器端重定向到首页
            return "redirect:/";
        }
        // 4:否则代表没有登录,直接去登录页面
        return "login";
    }

07、改进代码–如果用户直接访问首页需要登录才能进入怎么处理呢?

 /**
     * Description: 首页
     * @throws Exception
     * @date 2021/12/9
     * @author li
     */
    @GetMapping(value = {"/", "/index"})
    public ModelAndView index(String cid, HttpSession session) {
        ModelAndView modelAndView = new ModelAndView();
        // 1:获取用户登录的信息
        User user = (User)session.getAttribute(KConstants.SESSION_USER);
        // 2:如果没有登录
        if(user==null){
            // 3:直接服务器端重定向到登录进行登录
            modelAndView.setViewName("redirect:/login");
            return modelAndView;
        }
        // 4: 把查询分类放入到数据模型中
        modelAndView.addObject("blogCategories", blogCategoryService.findBlogCategies());
        modelAndView.addObject("cid", Optional.ofNullable(cid).orElse("0"));
        // 5: 跳转视图模板
        modelAndView.setViewName("index");
        return modelAndView;
    }

未来特别是在做个人中心,后台的时候,大部分情况都是一定登录的,所以如果每个地方都去做这这样的判断就显得很鸡肋,所以后面必须要使用:拦截器来进行统一处理。后续进行。

08、改进代码—关于登录用户渲染到用户问题

08-01、第一个解决方案:直接用freemarker语法进行渲染

定义一个公共的头部如下:

在这里插入图片描述

内容如下:

<div style="height: 50px;line-height: 50px;background: #fff;text-align: center;color:#333">
    当前登录的用户是:${sessionuser.nickname} <a href="/logout">退出</a>
</div>
头部页面进行包含

在index.html和detail.html需要进行头部页面包含即可:

<#include "/common/header.html"/>

08-02、第二种用异步axios

第一步:定义个js/common/common.js
第二步:后端定义一个接口返回session用户信息
   /**
     * 异步获取session中用户信息
     *
     * @return
     */
    @PostMapping("/login/loadsession")
    @ResponseBody
    public User toSessionUser(HttpSession session) {
        return (User) session.getAttribute(KConstants.SESSION_USER);
    }
第三步:每个页面都也如common.js

09、改进代码—关于退出

    /**
     * 退出
     * @return
     */
    @GetMapping("/logout")
    public String logout(HttpSession session) {
        // 注销所有的session
        session.invalidate();
        // 2:否则代表没有登录,直接去登录页面
        return "redirect:/login";
    }
```java

@ResponseBody
    public User toSessionUser(HttpSession session) {
        return (User) session.getAttribute(KConstants.SESSION_USER);
    }
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值