vue+springboot 登录注册功能

一、前端

1、搭建前端项目

需要用到node的npm,先下载安装node,官网https://nodejs.org/zh-cn/
vue+springboot 登录注册功能_第1张图片
在命令窗口输入命令:

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

在本地新建一个项目文件夹,打开命令窗口cd到项目文件夹,然后按下图操作:(只有一个输入No,其他Yes)
vue+springboot 登录注册功能_第2张图片
完成后:
vue+springboot 登录注册功能_第3张图片

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、目录结构

vue+springboot 登录注册功能_第4张图片

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: ''
})

二、后端

1、搭建后端项目

vue+springboot 登录注册功能_第5张图片vue+springboot 登录注册功能_第6张图片vue+springboot 登录注册功能_第7张图片vue+springboot 登录注册功能_第8张图片vue+springboot 登录注册功能_第9张图片

2、设计数据库(user表)

vue+springboot 登录注册功能_第10张图片

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

未完待续…

你可能感兴趣的:(前后端项目,vue,spring,boot)