【畅购商城】用户登录
创始人
2024-03-31 07:22:24
0
    1. 用户登录
      1. 构建页面:Login.vue
  1. 步骤一:创建Login.vue

  1. 步骤二:绘制通用模块

  1. 步骤三:绘制登录表单

      1. 分析

      1. 验证码:接口

http://localhost:10010/web-service/verifycode?username=jack

      1. 验证码:生成与显示
  1. 步骤一:后端生产验证码,并将用户保存Redis
    1. 存放redis中验证码key格式:"login" + 用户名

package com.czxy.changgou4.controller;

import org.springframework.data.redis.core.StringRedisTemplate;

import org.springframework.stereotype.Controller;

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

import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;

import javax.imageio.ImageIO;

import javax.servlet.http.HttpServletResponse;

import java.awt.*;

import java.awt.image.BufferedImage;

import java.io.IOException;

import java.util.Random;

import java.util.concurrent.TimeUnit;

/**

 * @author 桐叔

 * @email liangtong@itcast.cn

 */

@Controller

@RequestMapping("/verifycode")

public class VerifyCodeController {

    @Resource

    private StringRedisTemplate stringRedisTemplate;

    @GetMapping

    public void verifyCode(String username , HttpServletResponse response ) throws IOException {

        //字体只显示大写,去掉了1,0,i,o几个容易混淆的字符

        String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";

        int IMG_WIDTH = 72;

        int IMG_HEIGTH = 27;

        Random random = new Random();

        //创建图片

        BufferedImage image = new BufferedImage(IMG_WIDTH, IMG_HEIGTH, BufferedImage.TYPE_INT_RGB);

        //画板

        Graphics g = image.getGraphics();

        //填充背景

        g.setColor(Color.WHITE);

        g.fillRect(1,1,IMG_WIDTH-2,IMG_HEIGTH-2);

        g.setFont(new Font("楷体", Font.BOLD,25));

        StringBuilder sb = new StringBuilder();

        //写字

        for(int i = 1 ; i <= 4 ; i ++){

            //随机颜色

            g.setColor(new Color(random.nextInt(255),random.nextInt(255),random.nextInt(255)));

            int len = random.nextInt(VERIFY_CODES.length());

            String str = VERIFY_CODES.substring(len,len+1);

            sb.append(str);

            g.drawString(str, IMG_WIDTH / 6 * i , 22 );

        }

        //将验证码存放到redis

        stringRedisTemplate.opsForValue().set( "login" + username , sb.toString() , 1 , TimeUnit.HOURS);

        // 生成随机干扰线

        for (int i = 0; i < 30; i++) {

            //随机颜色

            g.setColor(new Color(random.nextInt(255),random.nextInt(255),random.nextInt(255)));

            int x = random.nextInt(IMG_WIDTH - 1);

            int y = random.nextInt(IMG_HEIGTH - 1);

            int x1 = random.nextInt(12) + 1;

            int y1 = random.nextInt(6) + 1;

            g.drawLine(x, y, x - x1, y - y1);

        }

        //响应到浏览器

        ImageIO.write(image,"jpeg", response.getOutputStream());

    }

}

  1. 步骤二:点击“换一张”显示验证码
    1. 默认不显示验证码
    2. 点击“换一张”获得验证码

      1. 通过用户名查询:接口

POST http://localhost:10010/web-service/user/findByUsername

{

"username":"jack"

}

      1. 通过用户名查询:实现
  1. 修改UserController,添加 findByUsername函数

/**

 * 通过用户名查询

 * @param user

 * @return 返回用户对象

 */

@PostMapping("/findByUsername")

public User findByUsername(@RequestBody User user){

    //查询用户

    User findUser = userService.findByUsername( user.getUsername() );

    return findUser;

}

      1. 认证服务:构建项目(changgou4-service-auth)
  1. 步骤一:构建项目

  1. 步骤二:创建pom.xml文件

<dependencies>

    

    <dependency>

        <groupId>com.czxy.changgougroupId>

        <artifactId>changgou4_common_authartifactId>

    dependency>

    

    <dependency>

        <groupId>org.springframework.bootgroupId>

        <artifactId>spring-boot-starter-webartifactId>

    dependency>

    

    <dependency>

        <groupId>com.alibaba.nacosgroupId>

        <artifactId>nacos-clientartifactId>

    dependency>

    

    <dependency>

        <groupId>com.alibaba.cloudgroupId>

        <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>

    dependency>

    

    <dependency>

        <groupId>org.springframework.bootgroupId>

        <artifactId>spring-boot-starter-data-redisartifactId>

    dependency>

    <dependency>

        <groupId>redis.clientsgroupId>

        <artifactId>jedisartifactId>

    dependency>

    

    <dependency>

        <groupId>io.springfoxgroupId>

        <artifactId>springfox-swagger2artifactId>

    dependency>

    <dependency>

        <groupId>io.springfoxgroupId>

        <artifactId>springfox-swagger-uiartifactId>

    dependency>

        

        

            org.springframework.cloud

            spring-cloud-starter-openfeign

        

dependencies>

  1. 步骤三:创建yml文件

server:

  port: 8085

spring:

  application:

    name: auth-service

  cloud:

    nacos:

      discovery:

        server-addr: 127.0.0.1:8848   #nacos服务地址

sc:

  jwt:

    secret: sc@Login(Auth}*^31)&czxy% # 登录校验的密钥

    pubKeyPath: D:/rsa/rsa.pub # 公钥地址

    priKeyPath: D:/rsa/rsa.pri # 私钥地址

    expire: 360 # 过期时间,单位分钟

  1. 步骤四:配置启动类

package com.czxy.changgou4;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

import org.springframework.cloud.openfeign.EnableFeignClients;

/**

 * @author 桐叔

 * @email liangtong@itcast.cn

 */

@SpringBootApplication

@EnableDiscoveryClient

@EnableFeignClients

public class CGAuthServiceApplication {

    public static void main(String[] args) {

        SpringApplication.run(CGAuthServiceApplication.class, args);

    }

}

  1. 步骤五:配置类

      1. 认证服务:用户登录后端
  1. 步骤一:创建AuthUser 封装对象(与User比较,缺数据库相关注解)

package com.czxy.changgou4.domain;

import lombok.Data;

import java.util.Date;

/**

 * @author 桐叔

 * @email liangtong@itcast.cn

 */

@Data

public class AuthUser {

    private Long id;

    private String username;

    private String password;

    private String face;

    private Integer expriece;

    private String email;

    private String mobile;

    private Date createdAt;

    private Date updatedAt;

    private String code;

    private String password_confirm;

}

  1. 步骤二:创建UserFeign,完成远程用户查询功能

package com.czxy.changgou4.feign;

import com.czxy.changgou4.domain.AuthUser;

import org.springframework.cloud.openfeign.FeignClient;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestBody;

/**

 * @author 桐叔

 * @email liangtong@itcast.cn

 */

@FeignClient(value = "web-service",path="/user")

public interface UserFeign {

    @PostMapping("/findByUsername")

    public AuthUser findByUsername(@RequestBody AuthUser user);

}

  1. 步骤三:创建AuthService接口,编写登录方法 login()

package com.czxy.changgou4.service;

import com.czxy.changgou4.domain.AuthUser;

/**

 * @author 桐叔

 * @email liangtong@itcast.cn

 */

public interface AuthService {

    /**

     * 用户登录

     * @param user

     * @return

     */

    public AuthUser login(AuthUser user ) ;

}

  1. 步骤四:创建AuthService实现类,并通过BCrypt校验密码

package com.czxy.changgou4.service.impl;

import com.czxy.changgou4.domain.AuthUser;

import com.czxy.changgou4.feign.UserFeign;

import com.czxy.changgou4.service.AuthService;

import com.czxy.changgou4.utils.BCrypt;

import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**

 * @author 桐叔

 * @email liangtong@itcast.cn

 */

@Service

public class AuthServiceImpl implements AuthService {

    @Resource

    private UserFeign userFeign;

    /**

     * 用户登录

     * @param user

     * @return

     */

    public AuthUser login(AuthUser user ) {

        //远程查询用户

        AuthUser findUser = userFeign.findByUsername(user);

        if(findUser == null) {

            return null;

        }

        //校验密码是否正确

        boolean checkpw = BCrypt.checkpw( user.getPassword(), findUser.getPassword());

        if(checkpw){

            return findUser;

        }

        return null;

    }

}

  1. 步骤五:创建AuthController,添加login方法
    1. redis中登录验证码和用户输入的验证码进行匹配

package com.czxy.changgou4.controller;

/**

 * @author 桐叔

 * @email liangtong@itcast.cn

 */

import com.czxy.changgou4.domain.AuthUser;

import com.czxy.changgou4.service.AuthService;

import com.czxy.changgou4.vo.BaseResult;

import org.springframework.data.redis.core.StringRedisTemplate;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**

 * Created by liangtong.

 */

@RestController

@RequestMapping("/auth")

public class AuthController {

    @Resource

    private AuthService authService;

    @Resource

    private StringRedisTemplate stringRedisTemplate;

    @PostMapping("/login")

    public BaseResult login(@RequestBody AuthUser user){

        //校验验证码--使用后删除

        String redisCode = stringRedisTemplate.opsForValue().get( "login" + user.getUsername() );

        stringRedisTemplate.delete( "login" + user.getUsername() );

        if(redisCode == null) {

            return BaseResult.error("验证码无效");

        }

        if(! redisCode.equalsIgnoreCase(user.getCode())) {

            return BaseResult.error("验证码错误");

        }

        //登录

        AuthUser loginUser = authService.login(user);

        if(loginUser != null ) {

            return BaseResult.ok("登录成功").append("loginUser",loginUser);

        } else {

            return BaseResult.error("用户名或密码不匹配");

        }

    }

}

      1. 认证服务:用户登录前端
  1. 步骤一:修改apiclient.js,添加login函数

  //登录

  login : ( user )=> {

    return axios.post('/auth-service/auth/login', user )

  }

  1. 步骤二:修改Login.vue,给验证码绑定变量

                验证码:

                

                

  1. 步骤三:修改Login.vue,给提交按钮绑定事件

  •                  

                    

                  

    1. 步骤四:编写loginFn完成登录功能
      1. 登录成功,跳转到首页
      2. 登录失败,给出提示

        async loginFn() {

          let { data } = await this.$request.login( this.user )

          if( data.code == 20000) {

            //成功

            sessionStorage.setItem('user' , JSON.stringify(data.other.loginUser) )

            //跳转到首页

            this.$router.push('/')

          } else {

            this.errorMsg = data.message

          }

        }

    1. 步骤五:创建首页 ~/pages/index.vue, 

    1. 步骤六:重命名静态页面 ~/static/index.html 为 ~/static/home.html

        1. 修改 TopNav.vue 组件

    1. 完善导航条,根据vuex中的数据,显示不同内容

    1. 步骤一:创建 ~/store/index.js ,并编写vuex内容

    export const state = () => ({

      user: null

    })

    //通用设置

    export const mutations = {

      setData( state , obj) {

        state[obj.key] = obj.value

      }

    }

    1. 步骤二:页面登录成功,将用户信息保存到vuex中

    // 将用户信息保存到vuex中

    this.$store.commit('setData', {key:'user',value: data.data })

    1. 步骤三:修改顶部导航TopNav.vue
      1. 从vuex中的数据

        1. vuex刷新数据丢失
    1. 刷新操作:
      1. 点击刷新按钮
      2. 点击回退按钮
      3. 地址栏直接输入地址
    2. 现象:
      1. vuex在刷新操作后,数据丢失了
    3. 解决方案
      1. 方案1:不是公共组件:页面在pages目录下,可以nuxt.js提供 fetch进行操作。
      2. 方案2:是公共组件:组件在components目录下,借助第三方进行存储(cookie、localStorage、sessionStorage)
        1. 选择1:sessionStorage存放数据,如果vuex中没有,将sessionStorage同步过去。
        2. 选择2:vuex中actions模块就可以发送ajax,从而同步数据。
    4. 具体操作:
      1. 如果vuex中没有数据,使用sessionStorage的数据填充vuex。
      2. 修改TopNav.vue页面

    相关内容

    热门资讯

    保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
    汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
    不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
    不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
    本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
    表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
    表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
    Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
    【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
    银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...