山东大学软件学院项目实训-创新实训-网络安全靶场实验平台(三)

目录

前言

一、项目目录结构

二、登录注册功能

2.1 前端

2.2 后端

三、跨域问题


前言

经过前端Vue的环境配置及学习,基本页面都已经编写好了,只是缺少美化布局的工作。

后端的环境也已经配置完成,本篇博客主要是记录后端springboot的学习以及部分配置代码的编写。

一、项目目录结构

整个项目分为Vue部分和springboot部分,Vue部分的项目目录结构在之前的博客里已经有过介绍,因此就不再赘述。

以下是springboot的目录结构:

在这里插入图片描述

• entity:实体类,记录数据库表结构

• mapper:负责与数据库打交道。具体到对某个表、某个实体的增删改查

• service:服务层或业务层,封装mapper层的操作,使一个方法对外表现为实现一种功能

• controller:业务控制层,负责接收数据和请求,并且调用Service层实现这个业务逻辑。接受页面过来的参数,传给Service处理,接到返回值,再传给页面。

二、登录注册功能

2.1 前端

主要代码:

Login.vue

<template>
  <div class="wrapper">
    <div
        style="margin: 200px auto; background-color: #fff; width: 350px; height: 300px; padding: 20px; border-radius: 10px">
      <div style="margin: 20px 0; text-align: center; font-size: 24px"><b>登 录</b></div>
      <el-form :model="user" :rules="rules" ref="userForm">
        <el-form-item prop="username">
          <el-input size="medium" style="margin: 10px 0" prefix-icon="el-icon-user" v-model="user.username"></el-input>
        </el-form-item>
        <el-form-item prop="password">
          <el-input size="medium" style="margin: 10px 0" prefix-icon="el-icon-lock" show-password v-model="user.password"></el-input>
        </el-form-item>
        <el-form-item style="margin: 10px 0; text-align: right">
          <el-button type="warning" size="small" autocomplete="off" @click="$router.push('/register')">注册</el-button>
          <el-button type="primary" size="small" autocomplete="off" @click="login">登录</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script>
import router from '../router/index.js'
import request from "../utils/request";
export default {
  name: "Login",
  components:{

  },
  data() {
    return {
      user: {},
      rules: {
        username: [
          {required: true, message: '请输入用户名', trigger: 'blur'},
          {min: 2, max: 10, message: '长度在 3 到 5 个字符', trigger: 'blur'}
        ],
        password: [
          {required: true, message: '请输入密码', trigger: 'blur'},
          {min: 1, max: 20, message: '长度在 1 到 20 个字符', trigger: 'blur'}
        ],
      }
    }
  },
  methods: {
    login() {
      request.post("/user/login", this.user).then(res => {
        if (res.code === '200') {
          localStorage.setItem("user", JSON.stringify(res.data))  // 存储用户信息到浏览器
          router.push("/")
        } else {
          this.$message.error(res.msg)
        }
      })
    }
  }
}
</script>

<style>
.wrapper {
  height: 100vh;
  background-image: linear-gradient(to bottom right, #000000, 	#483D8B);
  overflow: hidden;
}
</style>

 Register.vue部分代码,  与Login.vue类似

<template>
  <div class="wrapper">
    <div style="margin: 100px auto; background-color: #fff; width: 350px; height: 450px; padding: 20px; border-radius: 10px">
      <div style="margin: 20px 0; text-align: center; font-size: 24px"><b>注 册</b></div>
      <el-form :model="user" :rules="rules" ref="userForm">
            //省略
      </el-form>
    </div>
  </div>
</template>

<script>
import request from "../utils/request";
import router from "@/router";
export default {
  name: "Login",
  data() {
    return {
      user: {},
      rules: {
            //省略
      }
    }
  },
  methods: {
    register() {
      if (this.user.password !== this.user.confirmPassword) {
        this.$message.error("两次输入的密码不一致")
        return false
      }
      request.post("/user/register", this.user).then(res => {
        if(res.code === '200') {
          this.$message.success("注册成功")
          router.push("/login")
        } else {
          this.$message.error(res.msg)
        }
      })
    }
  }
}
</script>

 界面:

2.2 后端

 User.java  用户实体类

@Data
@TableName("user")
public class User implements Serializable {

    @TableId(type = IdType.AUTO)
    private Integer userid;
    private String username;
    private String password;
    private String realname;
    private String phone;
    private Integer role;

}

UserDTO.java  用户数据传输对象:

/**
 * 接受前端登录请求的参数
 */
@Data
public class UserDTO {
    private Integer userid;
    private String username;
    private String password;
    private String realname;
}

UserService.java

    @Override
    public UserDTO login(UserDTO userDTO) {
        User one = getUserInfo(userDTO);
        if (one != null) {
            BeanUtil.copyProperties(one, userDTO, true);
            //设置token
            String token= TokenUtils.genToken(one.getUserid().toString(),one.getPassword().toString());
            userDTO.setToken(token);
            return userDTO;
        } else {
            throw new ServiceException(Constants.CODE_600, "用户名或密码错误");
        }
    }

    @Override
    public User register(UserDTO userDTO) {
        User one = getUserInfo(userDTO);
        if (one == null) {
            one = new User();
            BeanUtil.copyProperties(userDTO, one, true);
            // 默认学生
            one.setRole(1);
            save(one);  // 把 copy完之后的用户对象存储到数据库
        } else {
            throw new ServiceException(Constants.CODE_600, "用户已存在");
        }
        return one;
    }

    private User getUserInfo(UserDTO userDTO) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", userDTO.getUsername());
        queryWrapper.eq("password", userDTO.getPassword());
        User one;
        try {
            one = getOne(queryWrapper); // 从数据库查询用户信息
        } catch (Exception e) {
            LOG.error(e);
            throw new ServiceException(Constants.CODE_500, "系统错误");
        }
        return one;
    }

UserController.java

    @PostMapping("/login")
    public Result login(@RequestBody UserDTO userDTO){
        String username = userDTO.getUsername();
        String password = userDTO.getPassword();
        if (StrUtil.isBlank(username) || StrUtil.isBlank(password)) {
            return Result.error(Constants.CODE_400, "参数错误");
        }
        UserDTO dto = userService.login(userDTO);
        return Result.success(dto);
    }

    @PostMapping("/register")
    public Result register(@RequestBody UserDTO userDTO) {
        String username = userDTO.getUsername();
        String password = userDTO.getPassword();
        if (StrUtil.isBlank(username) || StrUtil.isBlank(password)) {
            return Result.error(Constants.CODE_400, "参数错误");
        }
        return Result.success(userService.register(userDTO));
    }

三、跨域问题

完成上述代码后,点击运行,发现功能实现不了,原来是出现了跨域问题。报错如下:

为了解决跨域问题,可以在springboot中加入配置文件 CorsConfig.java,具体代码如下:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {

    // 当前跨域请求最大有效时长。这里默认1天
    private static final long MAX_AGE = 24 * 60 * 60;

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
        corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
        corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
        corsConfiguration.setMaxAge(MAX_AGE);
        source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置
        return new CorsFilter(source);
    }
}

当然,也可以在前端加入配置文件解决跨域问题,效果是一样的 vue.config.js

// 跨域配置
module.exports = {
    devServer: {                //记住,别写错了devServer//设置本地默认端口  选填
        port: 8080,
        proxy: {                 //设置代理,必须填
            '/api': {              //设置拦截器  拦截器格式   斜杠+拦截器名字,名字可以自己定
                target: 'http://localhost:9090',     //代理的目标地址
                changeOrigin: true,              //是否设置同源,输入是的
                pathRewrite: {                   //路径重写
                    '^/api': ''                     //选择忽略拦截器里面的内容
                }
            }
        }
    }
}

解决了问题之后,登录注册功能就实现了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值