vue+springboot 登錄註冊功能

一、前端

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

未完待續…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章