vue+springboot 登录注册功能

前后端项目 专栏收录该内容
3 篇文章 0 订阅

一、前端

1、搭建前端项目

需要用到node的npm,先下载安装node,官网https://nodejs.org/zh-cn/
在这里插入图片描述
在命令窗口输入命令:

npm -v
node -v
npm install webpack -g
npm install vue-cli -g

在本地新建一个项目文件夹,打开命令窗口cd到项目文件夹,然后按下图操作:(只有一个输入No,其他Yes)
在这里插入图片描述
完成后:
在这里插入图片描述

2、用VScode打开项目文件夹即可

3、安装element ui

在控制台输入命令:

npm i element-ui -S

4、在main.js中引入

import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI);

5、目录结构

在这里插入图片描述

6、新建register.vue组件

<template>
  <body id="paper">
  <el-form :model="registerForm" :rules="rules" class="login-container" label-position="left"
           label-width="0px" v-loading="loading">
    <h3 class="login_title">用户注册</h3>
    <el-form-item prop="username">
      <el-input type="text" v-model="registerForm.username"
                auto-complete="off" placeholder="账号"></el-input>
    </el-form-item>
    <el-form-item prop="password">
      <el-input type="password" v-model="registerForm.password"
                auto-complete="off" placeholder="密码"></el-input>
    </el-form-item>
    <el-form-item prop="passwordConfirm">
      <el-input type="password" v-model="registerForm.passwordConfirm"
                auto-complete="off" placeholder="确认密码"></el-input>
    </el-form-item>

    <el-form-item style="width: 100%">
      <el-button type="primary" style="width: 100%;background: #505458;border: none;" v-on:click="register">立即注册</el-button>
    </el-form-item>
    <el-form-item style="width: 100%">
      <el-button type="primary" style="width: 100%;background: #505458;border: none;" v-on:click="tologin">返回</el-button>
    </el-form-item>
  </el-form>
  </body>
</template>

<script>
export default{
  name: 'Register',
  data () {
    return {
      rules: {
        username: [{required: true, message: '用户名不能为空', trigger: 'blur'}],
        password: [{required: true, message: '密码不能为空', trigger: 'blur'}],
        passwordConfirm: [{required: true, message: '密码不能为空', trigger: 'blur'}]
      },
      checked: true,
      registerForm: {
        username: '',
        password: '',
        passwordConfirm: ''
      },
      loading: false
    }
  },
  methods: {
    register () {
      var _this = this
      if (this.registerForm.password !== this.registerForm.passwordConfirm) {
        this.$message({
          message: '两次输入的密码不一致',
          type: 'error'
        })
        return
      }
      this.axios.post("/register",{
            username:this.registerForm.username,
            password:this.registerForm.password,
          })
        .then(function (response) {
            // console.log(response.data.status)
            if(response.data.status === 200){
              alert("恭喜你,注册成功")
            //   _this.$message({
            //   message: '恭喜你,注册成功',
            //   type: 'success'
            // })
            _this.$router.replace('/login')
            }
            else {
              _this.$message({
              message: '该用户名已存在,请更换一个',
              type: 'error'
            })
            }
          })
        .catch(function (error) {
            console.log(error)
          })
    },
    tologin () {
      this.$router.replace('/login')
    }
  }
}
</script>

<style>
  #paper {
    /*background:url("../assets/img/bg/eva1.jpg") no-repeat;*/
    background-position: center;
    height: 100%;
    width: 100%;
    background-size: cover;
    position: fixed;
  }
  body{
    margin: -5px 0px;
  }
  .login-container {
    border-radius: 15px;
    background-clip: padding-box;
    margin: 160px auto;
    width: 350px;
    padding: 35px 35px 15px 35px;
    background: #fff;
    border: 1px solid #eaeaea;
    box-shadow: 0 0 25px #cac6c6;
  }
  .login_title {
    margin: 0px auto 40px auto;
    text-align: center;
    color: #505458;
  }
  .login_remember {
    margin: 0px 0px 35px 0px;
    text-align: left;
  }
</style>

7、新建login.vue组件

<template>
  <div>
    <body id="poster">
    <el-form class="login-container" label-position="left"
             label-width="0px">
      <h3 class="login_title">系统登录</h3>
      <el-form-item>
        <el-input type="text" v-model="loginForm.username"
                  auto-complete="off" placeholder="账号"></el-input>
      </el-form-item>
      <el-form-item>
        <el-input type="password" v-model="loginForm.password"
                  auto-complete="off" placeholder="密码"></el-input>
      </el-form-item>
      <el-form-item style="width: 100%">
        <el-button type="primary" style="width: 100%;background: #505458;border: none" v-on:click="login">登录</el-button>
      </el-form-item>
      <el-form-item style="width: 100%">
        <el-button type="primary" style="width: 100%;background: #505458;border: none" v-on:click="toregister">没有账号?去注册</el-button>
      </el-form-item>
       <el-form-item style="width: 100%">
        <el-button type="primary" style="width: 100%;background: #505458;border: none" v-on:click="tohome">游客模式</el-button>
      </el-form-item>
    </el-form>
    </body>
    <div></div>
  </div>
</template>
<script>
    export default {
      name: "Login",
      data() {
        return {
          loginForm:{
            username:'admin',
            password:'123'
          }
        }
      },
      methods: {
        login(){
          var _this = this
          this.axios.post("/login",{
            username:this.loginForm.username,
            password:this.loginForm.password,
          })
          .then(function (response) {
            // console.log(response.data.status)
            if(response.data.status === 200){
              _this.$message({
                message: '登录成功',
                type: 'success'
              })
              _this.$store.commit('login',response.data.object)
              // _this.$router.push({path: '/'})
              var path = _this.$route.query.redirect
              _this.$router.replace({path:path === undefined ? '/' : path})
            }
            else {
              // alert("账号或密码错误")
              _this.$message({
              message: '账号或密码错误',
              type: 'error'
            })
            }
          })
          .catch(function (error) {
            console.log(error)
          })
        },
        toregister(){
          this.$router.replace('/register')
        },
        tohome(){
          this.$router.replace('/home')
        }
      }
    }
</script>


<style>
  #poster {
    background-image: url("../../static/homeMask.png");
    height: 100%;
    width: 100%;
    background-size: cover;
    position: fixed;
  }

  body {
    margin: 0px;
  }

  .login-container {
    border-radius: 15px;
    background-clip: padding-box;
    margin: 90px auto;
    width: 350px;
    padding: 35px 35px 15px 35px;
    background: #fff;
    border: 1px solid #eaeaea;
    box-shadow: 0 0 25px #cac6c6;
  }

  .login_title {
    margin: 0px auto 40px auto;
    text-align: center;
    color: #505458;
  }

</style>

8、在router/index.js引入组件并配置路由

import Vue from 'vue'
import Router from 'vue-router'
import Register from "../components/Register";
import Login from "../components/Login";
import Home from "../components/home/Home";

Vue.use(Router)

export default new Router({
  mode: 'history',
  routes: [
    {
      path: '/register',
      name: 'Register',
      component: Register
    },
    {
      path: '/login',
      name: 'Login',
      component: Login
    }
  ]
})

9、main.js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'

import axios from 'axios'
import VueAxios from 'vue-axios'

import store from "./store";


Vue.config.productionTip = false
Vue.use(ElementUI);

axios.defaults.baseURL = "/api"
axios.defaults.withCredentials = true
Vue.use(VueAxios,axios);

Vue.use(mavonEditor)

router.beforeEach((to,from,next) =>{
  if(to.meta.requireAuth){
    // alert(store.state.currentUser)
    if(store.state.currentUser !== null && store.state.currentUser){
      next()
    }
    else{
      next({
        path:'/login',
        query: {redirect: to.fullPath}
      })
    }
  }
  else{
    next()
  }
})

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

二、后端

1、搭建后端项目

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

2、设计数据库(user表)

在这里插入图片描述

3、pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.southwind</groupId>
    <artifactId>springboottest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboottest</name>
    <description>Demo project for Spring Boot</description>
    <packaging>jar</packaging>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <!-- springboot tomcat 支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <!--jpa-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--shiro-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <!-- mvn 打包依赖 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
        </plugins>

    </build>

</project>

4、新建pojo包,在pojo包下新建User

User.java

package com.southwind.springboottest.entity;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import javax.persistence.*;

@Entity
@Table(name = "user")
@JsonIgnoreProperties({"heandler","hibernateLazyInitializer"})
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    int id;
    String username;
    String password;
    String salt;

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getSalt() {
        return salt;
    }

    public void setSalt(String salt) {
        this.salt = salt;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}

5、新建dao包,在dao包下新建UserDao

UserDao.java

package com.southwind.springboottest.repository;

import com.southwind.springboottest.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Integer> {
    User findByUsername(String username);
}

6、新建service包,在service包下新建UserService

UserService.java

package com.southwind.springboottest.service;

import com.southwind.springboottest.entity.User;
import com.southwind.springboottest.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    @Autowired
    UserRepository userRepository;

    public User getUserByUsername(String username){
        return userRepository.findByUsername(username);
    }

    public boolean isExist(String username){
        User user = getUserByUsername(username);
        return user!=null;
    }

    public void addUser(User user){
        userRepository.save(user);
    }
}

7、新建controller包,在controller包下新建UserController

UserController.java

package com.southwind.springboottest.controller;

import com.southwind.springboottest.Response.Response;
import com.southwind.springboottest.entity.User;
import com.southwind.springboottest.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.HtmlUtils;

@Controller
public class UserController {
    @Autowired
    UserService userService;

    @CrossOrigin
    @PostMapping("api/register")
    @ResponseBody
    public Response Register(@RequestBody User user){
        String username = user.getUsername();
        username = HtmlUtils.htmlEscape(username);
        user.setUsername(username);
        String password = user.getPassword();

        boolean isExist = userService.isExist(username);
        if (isExist){
            return new Response(500,"failure",null);
        }
        String salt = new SecureRandomNumberGenerator().nextBytes().toString();
        int times = 2;
        String algorithm = "md5";
        String pwdAfterHash = new SimpleHash(algorithm,password,salt,times).toString();
        user.setSalt(salt);
        user.setPassword(pwdAfterHash);
        userService.addUser(user);
        return new Response(200,"success",null);
    }

    @CrossOrigin
    @PostMapping("api/login")
    @ResponseBody
    public Response login(@RequestBody User user){
        String username = user.getUsername();
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username,user.getPassword());

        try{
            subject.login(usernamePasswordToken);
            return new Response(200,"success",usernamePasswordToken);
        }catch (AuthenticationException e){
            return new Response(500,"failure",null);
        }
    }

    @CrossOrigin
    @GetMapping("api/logout")
    @ResponseBody
    public Response logout(){
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return new Response(200,"登出",null);
    }
}

8、application.yml

spring:
  datasource:
   
    url: jdbc:mysql://localhost:3306/user_country?useUnicode=true&characterEncoding=UTF-useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: root
    password: xxxxxx
    driver-class-name: com.mysql.jdbc.Driver
  jpa:
    show-sql: true
    properties:
      hibernate:
        format_sql: true
server:
  port: 8443

未完待续…

  • 9
    点赞
  • 5
    评论
  • 26
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

<p> <span style="font-size:24px;"><img src="https://img-bss.csdn.net/202002111502403886.png" alt="" /><br /> </span> </p> <p> <span style="font-size:24px;"><img src="https://img-bss.csdn.net/202002111502521739.jpg" alt="" /><br /> </span> </p> <p> <span style="font-size:24px;">本课程是Vue的快速入门课程,涉及到的课程知识点:Vue环境的快速搭建, 会使用Vue的生命周期的钩子函数; 会使用vue常见指令;会使用vue计算属性和watch监控;会编写Vue组件;掌握组件间通信,会创建Vue实例,知道Vue的常见属性</span> </p> <br /> <br /> <span style="font-size:24px;">大家都知道涛哥最关心的是找工作,这段时间出去面试的时候会经常会被问及到Vue相关的知识,所以涛哥迫不及待的赶紧出了一版Vue相关的教程,有人问:我们做后台会前台干什么呀?是因为现在的公司老板都想招复合型的人才,招一个Java开发回来恨不得前后台都会,所以我们Java开发人员也要掌握一些前端相关的技能。Java这边现在前端用的比较多的就是VUE,所以大家还是要赶紧学习起来,为了你不被淘汰,为了你能快速适应公司的发展速度,快速找到一份满意的工作,赶紧学起来吧。本课程是Vue的快速入门课程,涉及到的课程知识点:Vue环境的快速搭建,?会使用Vue的生命周期的钩子函数;?会使用vue常见指令;会使用vue计算属性和watch监控;会编写Vue组件;掌握组件间通信;</span><br /> <br /> <span style="font-size:24px;">用2小时看完,就可以快速上手公司里的项目,后期还会有实战项目上线,请大家持续关注。</span><br /> <br /> <span style="font-size:24px;"></span>
相关推荐
<div> 适用人群 <p> Java开发人员,Vue开发人员,前后端分离开发人员,权限管理和配置开发人员 </p> </div> <div> 课程概述 <div style="color:#666666;"> 【讲师介绍】<br /> 讲师职称:<br />               现某知名大型互联网公司资深架构师,技术总监,职业规划师,首席面试官,曾在某上市培训机构,高校任教多年。<br />             Array(Array老师)10多年互联网公司实战经验,知名的大型互联网公司的架构师,高管等职,在企业长期从事于技术的源码阅读和新技术的研究;擅长于职业规划,面试辅导,从事面试官多年;擅长于JAVA,人工智能AI应用,Xmind等等,曾服役于国内某上市培训机构数年,独特的培训思路,培训体系,培训方式,实践的职场技能,职场现状,职场晋升等让你快速适应企业职场的所需。 <br /> 【课程介绍】<br /> 技术选型<br /> 开发环境:Eclipse/Idea ,JDK 1.8以上 <br /> 后端技术<br /> 核心框架:SpringBoot2.x框架系列(同样适用Springcloud F版本以后的版本),如下(节选):    <br /> 持久层框架:MyBatis 3.x + Mybatis-plus 3.x<br /> 日志管理:SLF4J 1.7 + Log4j2 2.7<br /> 工具类:Apache Commons、Jackson 、fastjson、Gson<br /> 权限验证<br /> 前端技术  <br /> Vue  <br /> Vue-cli<br /> ElementUI ---https://element.eleme.io/<br /> JSX (JavaScript Xml)<br /> 前台的权限验证和路由设置<br /> 开发模式  <br />      前后端分离的开发<br /> 数据库 <br />       Mysql5<br /> IDE<br />     Intellij Idea </div> </div>
©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值