1、解决前后端跨域问题

image.png

  1. @Configuration
  2. public class CorsConfig implements WebMvcConfigurer {
  3. @Override
  4. public void addCorsMappings(CorsRegistry registry) {
  5. registry.addMapping("/**").allowedOriginPatterns("*")
  6. .allowedMethods("GET", "HEAD", "POST","PUT", "DELETE", "OPTIONS")
  7. .allowCredentials(true).maxAge(3600);
  8. }
  9. }

2、登录-后端代码

2.1 Service业务层

  1. /**
  2. * <p>
  3. * 管理员表 服务类
  4. * </p>
  5. *
  6. * @author 未进化的程序猿
  7. * @since 2022-01-26
  8. */
  9. public interface AdminService extends IService<Admin> {
  10. /**
  11. * 校验用户名和密码是否正确
  12. * @param username 用户名
  13. * @param password 密码
  14. * @return
  15. */
  16. public boolean checkPassword(String username,String password);
  17. }
  1. /**
  2. * <p>
  3. * 管理员表 服务实现类
  4. * </p>
  5. *
  6. * @author 未进化的程序猿
  7. * @since 2022-01-26
  8. */
  9. @Service
  10. public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {
  11. //导入管理dao
  12. @Autowired
  13. public AdminMapper adminMapper;
  14. /**
  15. * 校验用户名和密码是否正确
  16. * @param username 用户名
  17. * @param password 密码
  18. * @return
  19. */
  20. @Override
  21. public boolean checkPassword(String username, String password) {
  22. //如果根据用户名和密码查询返回的数量大于1,返回true,否则false
  23. QueryWrapper<Admin> wrapper = new QueryWrapper<>();
  24. wrapper.eq("username",username);
  25. wrapper.eq("password",password);
  26. Admin admin = this.baseMapper.selectOne(wrapper);
  27. if (admin != null){
  28. return true;
  29. }
  30. return false;
  31. }
  32. }

2.2 Controller控制层

  1. /**
  2. * <p>
  3. * 管理员表 前端控制器
  4. * </p>
  5. *
  6. * @author 未进化的程序猿
  7. * @since 2022-01-26
  8. */
  9. @RestController
  10. @RequestMapping("/musicserver/admin")
  11. @Api(value = "管理员登录控制器")
  12. public class AdminController {
  13. public static final Logger logger = LoggerFactory.getLogger(AdminController.class);
  14. @Autowired
  15. public AdminService adminService;
  16. /**
  17. * 校验用户名和密码是否正确
  18. * @param request
  19. * @param session
  20. * @return
  21. */
  22. @ApiOperation(value = "校验用户名和密码")
  23. @PostMapping(value = "/login/status")
  24. public R getLoginStatus(HttpServletRequest request, HttpSession session){
  25. String username = request.getParameter("username");
  26. logger.info("用户名: {}",username);
  27. String password = request.getParameter("password");
  28. logger.info("密码: {}",password);
  29. boolean flag = adminService.checkPassword(username, password);
  30. if(flag){
  31. //如果登录成功,生成token,返回给前端,下次客户端访问的时候,带上token进行校验
  32. return R.ok().message("登录成功!!");
  33. }
  34. return R.error().message("登录失败!!");
  35. }
  36. }

image.png

3、登录-前端代码

3.1 封装Http.js请求

image.png

  1. import axios from 'axios';
  2. import router from '../router';
  3. axios.defaults.timeout = 5000; //超市时间是5秒
  4. axios.defaults.withCredentials = true; //允许跨域
  5. //Content-Type 响应头
  6. axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
  7. //基础url
  8. axios.defaults.baseURL = "http://localhost:8888";
  9. //响应拦截器
  10. axios.interceptors.response.use(
  11. response => {
  12. //如果reponse里面的status是200,说明访问到接口了,否则错误
  13. if(response.status == 200){
  14. return Promise.resolve(response);
  15. }else{
  16. return Promise.reject(response);
  17. }
  18. },
  19. error => {
  20. if(error.response.status){
  21. switch(error.response.status){
  22. case 401: //未登录
  23. router.replace({
  24. path:'/',
  25. query:{
  26. redirect: router.currentRoute.fullPath
  27. }
  28. });
  29. break;
  30. case 404: //没找到
  31. break;
  32. }
  33. return Promise.reject(error.response);
  34. }
  35. }
  36. );
  37. /**
  38. * 封装get方法
  39. */
  40. export function get(url,params={}){
  41. return new Promise((resolve,reject) => {
  42. axios.get(url,{params:params})
  43. .then(response =>{
  44. resolve(response.data);
  45. })
  46. .catch(err =>{
  47. reject(err);
  48. })
  49. });
  50. }
  51. /**
  52. * 封装post方法
  53. */
  54. export function post(url,data={}){
  55. return new Promise((resolve,reject) => {
  56. axios.post(url,data)
  57. .then(response =>{
  58. resolve(response.data);
  59. })
  60. .catch(err =>{
  61. reject(err);
  62. })
  63. });
  64. }

3.2 编写前端请求方法

  1. import {get,post} from '../http'
  2. //判断管理员是否登录成功
  3. export const getLoginStatus = (params) => post('/musicserver/admin/login/status',params);

3.3 完成登录

image.png

  1. <template>
  2. <div class="login-wrap">
  3. <div class="ms-title">music 后台管理登录</div>
  4. <div class="ms-login">
  5. <el-form :model="ruleForm" :rules="rules" ref="ruleForm">
  6. <el-form-item prop="username">
  7. <el-input v-model="ruleForm.username" placeholder="请输入用户名" clearable></el-input>
  8. </el-form-item>
  9. <el-form-item prop="password">
  10. <el-input type="password" v-model="ruleForm.password" placeholder="请输入密码" show-password></el-input>
  11. </el-form-item>
  12. <div class="login-btn">
  13. <el-button type="primary" @click="submitForm('ruleForm')">登录</el-button>
  14. </div>
  15. </el-form>
  16. </div>
  17. </div>
  18. </template>
  19. <script>
  20. import {getLoginStatus} from '../api/login/index'
  21. export default {
  22. data() {
  23. return {
  24. ruleForm: {
  25. username: '',
  26. password: ''
  27. },
  28. rules: {
  29. username: [
  30. { required: true, message: '请输入用户名', trigger: 'blur' }
  31. ],
  32. password: [
  33. { required: true, message: '请输入密码', trigger: 'blur' }
  34. ]
  35. }
  36. };
  37. },
  38. methods: {
  39. submitForm(formName) {
  40. var _this = this;
  41. this.$refs[formName].validate((valid) => {
  42. if (valid) {
  43. // alert('submit!');
  44. //设置参数
  45. var params = new URLSearchParams();
  46. params.append("username",this.ruleForm.username);
  47. params.append("password",this.ruleForm.password);
  48. //向后端发送请求
  49. getLoginStatus(params).then((resp) => {
  50. //登录成功
  51. if(resp.code === 20000){
  52. //跳转到首页
  53. _this.$router.push("/Info");
  54. //给用户提出提示
  55. this.$notify({
  56. message: '登录成功',
  57. type: 'success'
  58. });
  59. }else{
  60. //登录失败
  61. this.$notify({
  62. message: '用户名或密码错误',
  63. type: 'error'
  64. });
  65. //清空输入框的内容
  66. _this.ruleForm.username='';
  67. _this.ruleForm.password='';
  68. }
  69. console.log(resp);
  70. })
  71. } else {
  72. console.log('error submit!!');
  73. return false;
  74. }
  75. });
  76. }
  77. }
  78. }
  79. </script>
  80. <style scoped>
  81. .login-wrap {
  82. position: relative;
  83. background: url("../assets/img/background.jpg");
  84. background-attachment: fixed;
  85. background-position: center;
  86. background-size: cover;
  87. width: 100%;
  88. height: 100%;
  89. }
  90. .ms-title {
  91. position: absolute;
  92. top: 50%;
  93. width: 100%;
  94. margin-top: -230px;
  95. text-align: center;
  96. font-size: 30px;
  97. font-weight: 600;
  98. color: #fff;
  99. }
  100. .ms-login {
  101. position: absolute;
  102. left: 50%;
  103. top: 50%;
  104. width: 300px;
  105. height: 160px;
  106. margin-left: -190px;
  107. margin-top: -150px;
  108. padding: 40px;
  109. border-radius: 5px;
  110. background: #fff;
  111. }
  112. /* .login-btn {
  113. text-align: center;
  114. } */
  115. .login-btn button {
  116. width: 100%;
  117. height: 36px;
  118. }
  119. </style>

var params = new URLSearchParams(); params.append(“username”,this.ruleForm.username); params.append(“password”,this.ruleForm.password);

创建new URLSearchParams(); 对象,设置参数值,提交给后端,通过HttpServletRequest获取请求参数

向后端发送请求,调用封装的getLoginStatus()方法,往后台发送数据

3.4 跳转到首页

image.png

4、扩展知识

image.png

封装mixins工具类,更好的去调用element-ui提供的通知方法

image.png

this.$notify({
  message: '登录成功',
  type: 'success'
});

代码封装,创建index.js

export const mixin = {
    methods:{
        //提示信息
        notify(title,type){
            this.$notify({
                title: title,
                type: type
            })
        }
    }
}

进行使用

1)导入index.js模块

import {mixin} from “../mixins/index”;

2)对mixins进行声明,才能使用

export default {
      mixins:[mixin],
        .....
}

3)使用

this.notify(“登录成功”,”success”);