前后端+数据库实现用户登录注册

资源学习教程博客
1.后端和数据库详细使用教程
2.前端详细教程

1.使用的软件

1.2 后端 IDEA;前端WebStrom;数据库 MySQL

2.过程要点

2.1 数据库

(1)在cmd面板里,启动,打开数据库
所使用的命令:

net start mysql //启动
mysql -u root -p // 打开

(2)新建,进入数据库 demo

create database demo
use demo

(3)创建用户信息数据表

CREATE TABLE user
(
    uid int(10) primary key NOT NULL AUTO_INCREMENT,
    uname varchar(30) NOT NULL,
    password varchar(255) NOT NULL,
    UNIQUE (uname)
);

(4)配置数据库

打开IDEA项目,找到src<-main<resources下的application.properties 写入

# 配置端口号
server.port=8081
#数据库驱动
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#其中demo是所建立的数据库名
spring.datasource.url=jdbc:mysql://localhost:3306/demo?serverTimezone=UTC
# Mysql用户
spring.datasource.username=root
# Mysql密码
spring.datasource.password=123456

2.2 后端

(1)创建注意
在这里插入图片描述
在这里插入图片描述
(2) 项目文件分布
在这里插入图片描述
(3)各文件作用及代码
User实体类:连接所用的数据表user,生成相关属性的get和set方法

package com.******.domain;
import javax.persistence.*;
@Table(name = "user") //连接的数据表
@Entity
public class User {
    public long getUid() { return uid;} 
    public void setUid(long uid) {  this.uid = uid;}
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long uid;
    public String getUname() { return uname;}
    public void setUname(String uname) { this.uname = uname;  }
    private String uname;
    public String getPassword() { return password;}
    public void setPassword(String password) { this.password = password; }
    private String password;
}

UserDao接口:通过用户名来访问数据库进行查询

package com.******.repository;
        import com.******.User;
        import org.springframework.data.jpa.repository.JpaRepository;
        import org.springframework.stereotype.Repository;
@Repository
public interface UserDao extends JpaRepository<User, Long> {
    User findByUname(String uname); 
    User findByUnameAndPassword(String uname, String password);
}

UserService接口:登录注册业务逻辑,传递参数

package com.******.service;
        import com.******.User;
public interface UserService {
    User loginService(String uname, String password);
    User registService(User user);
}

UserServiceImpl :实现登录注册业务逻辑的方法

package com.******.serviceImpl;
import com.******.User;
import com.******.UserDao;
import com.******.UserService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UserDao userDao;
    @Override
    public User loginService(String uname, String password) {
        User user = userDao.findByUnameAndPassword(uname, password);
        if(user != null){ user.setPassword(""); }
        return user;
    }
    @Override
    public User registService(User user) {
        if(userDao.findByUname(user.getUname())!=null){
             return null;
        }else{
            User newUser = userDao.save(user);
            if(newUser != null){ newUser.setPassword(""); }
            return newUser; }
    }
}

Result :模板类,很多静态方法可以用类名.方法名调用

package com.******.utils;
public class Result<T> {
    private String code;
    private String msg;
    private T data;
    public String getCode() { return code;  }
    public void setCode(String code) {  this.code = code; }
    public String getMsg() {  return msg;  }
    public void setMsg(String msg) {  this.msg = msg;  }
    public T getData() { return data;  }
    public void setData(T data) { this.data = data;  }
    public Result() {  }
    public Result(T data) { this.data = data; }
    public static Result success() {
        Result result = new Result<>();
        result.setCode("0");
        result.setMsg("成功");
        return result;
    }
    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>(data);
        result.setCode("0");
        result.setMsg("成功");
        return result;
    }
    public static <T> Result<T> success(T data,String msg) {
        Result<T> result = new Result<>(data);
        result.setCode("0");
        result.setMsg(msg);
        return result;
    }
    public static Result error(String code, String msg) {
        Result result = new Result();
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }
}

UserController :实现登录注册的控制,处理post请求方法@RequestMapping(“/user”)是控制器类的基路由

package com.******.controller;
        import com.******.User;
        import com.******.UserService;
        import com.******.Result;
        import org.springframework.web.bind.annotation.*;
        import javax.annotation.Resource;
@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    private UserService userService;
    @PostMapping("/login")
    public Result<User> loginController(@RequestParam String uname, @RequestParam String password){
        User user = userService.loginService(uname, password);
        if(user!=null){  return Result.success(user,"登录成功!");
        }else{ return Result.error("123","账号或密码错误!");  }
    }
    @PostMapping("/register")
    public Result<User> registController(@RequestBody User newUser){
        User user = userService.registService(newUser);
        if(user!=null){  return Result.success(user,"注册成功!");
        }else{  return Result.error("456","用户名已存在!");  }
    }
}

GlobalCorsConfig :全局跨域配置类,处理跨域问题,可有可无看具体运行是否报错,前后端分离

package com.******.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class GlobalCorsConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")   //添加映射路径,“/**”表示对所有的路径实行全局跨域访问权限的设置
                        .allowedOrigins("*") //开放哪些ip、端口、域名的访问权限
                        .allowCredentials(true)  //是否允许发送Cookie信息
                        .allowedMethods("GET", "POST", "PUT", "DELETE") //开放哪些Http方法,允许跨域访问
                        .allowedHeaders("*") //允许HTTP请求中的携带哪些Header信息
                        .exposedHeaders("*"); 暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
            }
        };
    }
}

2.3 前端

(1)创建配置
config / index.js 中 更改以下部分,其中8081是后端设置好的端口号

 proxy: {
      '/api': {
        target: 'http://localhost:8081',
        ws: true,
        changeOrigin: true, 
        pathRewrite: {
          '^/api': ''  
        }
      }
  },

src / main.js 中 ,添加部分,引用element和axios

import axios from 'axios'
import VueAxios from 'vue-axios' 
Vue.use(ElementUI) // element ui 插件 
Vue.use(VueAxios, axios) // 使用 axios 插件 

(2)文件目录在这里插入图片描述
(3)Login.vue 登录页面

<template>
  <div>
    <el-card class="box-card">
      <h2>登录</h2>
      <el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-position="left" label-width="70px" class="login-from">
        <el-form-item label="用户名" prop="uname">
          <el-input v-model="ruleForm.uname"></el-input>
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input type="password" v-model="ruleForm.password" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div class="btnGroup">
        <el-button type="primary" @click="submitForm('ruleForm')">登录</el-button>
        <el-button @click="resetForm('ruleForm')">重置</el-button>
        <router-link to="/register">
          <el-button style="margin-left: 10px">注册</el-button>
        </router-link>
      </div>
    </el-card>
  </div>
</template>

<script>
export default {
  data() {
    return {
      ruleForm: {
        uname: "",
        password: "",
      },
      rules: {
        uname: [
          { required: true, message: "用户名不能为空!", trigger: "blur" },
        ],
        password: [
          { required: true, message: "密码不能为空!", trigger: "blur" },
        ],
      }
    };
  },
  methods: {
    submitForm(formName) {
      // 验证表单中的账号密码是否有效,因为在上面rules中定义为了必填 required: true
      this.$refs[formName].validate((valid) => {
        // 如果经过校验,账号密码都不为空,则发送请求到后端登录接口
        if (valid) {
           let _this = this;
          // 使用 axios 将登录信息发送到后端
          this.axios({
            url: "/user/login",               // 请求地址
            method: "post",                       // 请求方法
            headers: {                            // 请求头
              "Content-Type": "application/json",
            },
            params: {                             // 请求参数
              uname: _this.ruleForm.uname,
              password: _this.ruleForm.password,
            },
          })
            .then((res) => { // 当收到后端的响应时执行该括号内的代码,res 为响应信息,也就是后端返回的信息
            if (res.data.code === "0") {  // 当响应的编码为 0 时,说明登录成功
              // 将用户信息存储到sessionStorage中
              sessionStorage.setItem("userInfo", JSON.stringify(res.data.data));
              // 跳转页面到首页
              this.$router.push('/home');
            }
            else {  // 当响应的编码不为 0 时,说明登录失败
              this.$message({
                message: res.data.msg,
                type: "warning",
              });
            }
              return false;
          });
        } else {  // 如果账号或密码有一个没填,就直接提示必填,不向后端请求
          console.log("error submit!!");
          return false;
        }
        return false;
      });
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
  },
};
</script>

<style scoped>
/* 设置登录面板居中,宽度为400px */
.box-card {
  margin: auto auto;
  width: 400px;
}
/* 设置登录面板中的表单居中 */
.login-from {
  margin: auto auto;
}
</style>

(4)Register.vue 注册页面

<template>
  <div>
    <el-card class="box-card">
      <h2>注册</h2>
      <el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm"
               label-position="left" label-width="80px" class="demo-ruleForm">
        <el-form-item label="用户名" prop="uname">
          <el-input v-model="ruleForm.uname"></el-input>
        </el-form-item>
        <el-form-item label="密码" prop="pass">
          <el-input
            type="password" v-model="ruleForm.pass" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="确认密码" prop="password">
          <el-input type="password" v-model="ruleForm.password" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div class="btnGroup">
        <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
        <el-button @click="resetForm('ruleForm')">重置</el-button>
        <el-button @click="goBack">返回</el-button>
      </div>
    </el-card>
  </div>
</template>

<script>
export default {
  data() {
    var validatePass = (rule, value, callback) => {
      if (value === "") {
        callback(new Error("请输入密码"));
      } else {
        if (this.ruleForm.checkPass !== "") {
          this.$refs.ruleForm.validateField("checkPass");
        }
        callback();
      }
    };
    var validatePass2 = (rule, value, callback) => {
      if (value === "") {
        callback(new Error("请再次输入密码"));
      } else if (value !== this.ruleForm.pass) {
        callback(new Error("两次输入密码不一致!"));
      } else {
        callback();
      }
    };
    return {
      ruleForm: {
        uname: "",
        pass: "",
        password: "",
      },
      rules: {
        uname: [{ required: true, message: "用户名不能为空!", trigger: "blur" }],
        pass: [{ required: true, validator: validatePass, trigger: "blur" }],
        password: [{ required: true, validator: validatePass2, trigger: "blur" }],
      }
    };
  },
  methods: {
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          let _this = this;
          this.axios({     // axios 向后端发起请求
            url: "/user/register",  // 请求地址
            method: "post",             // 请求方法
            headers: {                  // 请求头
              "ContentType": "application/json",
            },
            data: { // 请求参数,为 data,与登录的 params 不太一样
              uname: _this.ruleForm.uname,
              password: _this.ruleForm.password,
            },
          }).then((res) => { // 当收到后端的响应时执行该括号内的代码,res 为响应信息,也就是后端返回的信息
            if (res.data.code === '0') {  // 当响应的编码为 0 时,说明注册成功
              // 显示后端响应的成功信息
              this.$message({
                message: res.data.msg,
                type: "success",
              });
            }
            else{  // 当响应的编码不为 0 时,说明注册失败
              // 显示后端响应的失败信息
              this.$message({
                message: res.data.msg,
                type: "warning",
              });
            }
            return false;
          });
        } else { // 如果账号或密码有一个没填,就直接提示必填,不向后端请求
          console.log("error submit!!");
          return false;
        }
      });
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
    goBack() {
      this.$router.go(-1);
    },
  },
};
</script>

<style scoped>
/* 设置登录面板居中,宽度为400px */
.box-card {
  margin: auto auto;
  width: 400px;
}
/* 设置登录面板中的表单居中 */
.login-from {
  margin: auto auto;
}
</style>

router - index.js 配置路径

import Vue from 'vue'
import Router from 'vue-router' 
import Login from '../views/login/Login'
import Register from '../views/register/Register' 
Vue.use(Router)
export default new Router({
  routes: [
    {
      path: '/',          // 路径
      name:'login',
      redirect: '/login'  // 重定向
       component: Login  
    }, 
      {
      path: '/register',     // 路径
      name:'register',
      component: Register    // 跳转到的组件
    },
    {
      path: '/home', // 路径
      name:'Home',
      component: Home    // 跳转到的组件
    } 
  ]
})

后记碎碎念:
完整的小项目,数据库,后端,前端一起配合完成登录和注册
前前后后经历了一个月多的时间。
作为一个前端学习者,后端还是比较难,完全根据网上的博客和报错查询,做出来
逻辑还是不太清晰,但是其中需要注意的点是比较熟悉了。
继续加油吧!

  • 11
    点赞
  • 109
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
前端连接数据库通常需要使用后端语言(例如 PHP、Python、Java 等)来处理数据库的连接和操作,前端可以通过发送请求到后端来实现数据库的交互。以下是一个使用 PHP 连接数据库实现登录的例子: 1. 创建数据库 首先,需要在数据库创建一个用户,包含用户名和密码两个字段。 CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(255) NOT NULL, `password` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 2. 创建登录页面 在前端创建一个登录页面,包含用户名和密码输入框以及登录按钮。 ``` <form method="post" action="login.php"> <label>Username:</label> <input type="text" name="username" required><br> <label>Password:</label> <input type="password" name="password" required><br> <input type="submit" value="Login"> </form> ``` 3. 创建后端处理登录请求的 PHP 文件 在后端创建一个 PHP 文件,处理登录请求,连接数据库,验证用户名和密码是否正确。如果登录成功,则跳转到首页。 ``` <?php $conn = mysqli_connect("localhost", "username", "password", "database"); if (!$conn) { die("Connection failed: " . mysqli_connect_error()); } if ($_SERVER["REQUEST_METHOD"] == "POST") { $username = $_POST["username"]; $password = $_POST["password"]; $sql = "SELECT * FROM users WHERE username='$username' AND password='$password'"; $result = mysqli_query($conn, $sql); if (mysqli_num_rows($result) == 1) { header("Location: index.php"); exit(); } else { echo "Invalid username or password."; } } mysqli_close($conn); ?> ``` 以上是一个简单的前端连接数据库登录界面实现例子。需要注意的是,为了安全考虑,密码应该使用加密方式存储在数据库,且密码验证应该使用加密后的值进行比较。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值