【平台开发】— 6.从[登录]看前后端交互

简介: 【平台开发】— 6.从[登录]看前后端交互

上次了解到了后端代码的大概分层,作用都是干嘛的。那今天就结合着前端,一起看下它们是怎么交互的。


其实简单来讲,就是前端把数据传递给后端,后端拿到数据后一通处理再返回给前端。


一、登录功能


前面提到的前端模板vue-admin-template,在本地run起来后,其实就可以看出一些端倪。


打开登录页后,按下F12,点击到network下,再点击登录按钮。


1268169-20200720193702504-787725717.png


可以看到有2个请求:


  • login
  • info


1268169-20200720193735410-1546487047.png


其中,login接口的返回中,有一个token值。


而在info接口的请求参数中,带有这个token值。


这就是常见的登录了,后端验证用户名密码是否存在,存在的话返回一个token值给用户,那此用户后面的请求都需要带上这个token值。


不过这个前端框架run起来里的数据,都是通过mock模拟返回的,路径如图所示:


1268169-20200720193847123-293013115.png


那其实一个道理,我在后端实现同样的返回给前端处理不就可以了嘛?


二、登录-后端


根据前面讲过的后端代码分层,我这里直接贴上代码:


1.实体类User


@Entity
@Table(name = "user")
@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
@Data
public class User {
    @Id //声明一个字段“id”为数据库表的主键
    @GeneratedValue(strategy = GenerationType.AUTO) //标注主键的生成策略,通过strategy 属性指定
    @Column(name = "id") //被标注字段在数据库表中所对应字段的名称
    private int id; //用户id
    private String username; //用户名称
    private String password; //密码
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime; //创建时间
}


2.DAO类UserDAO


/**
 * UserDAO类继承JpaRepository,就提供了CRUD和分页 的各种常见功能。
 * JpaRepository<User, Integer>,参数分别是实体类,和这个实体类id的类型。
 */
public interface UserDAO extends JpaRepository<User, Integer> {
}


3.Service层UserService


这里的isUserExist方法就是用来判断输入的用户名密码是否可以查询到。

并且我在数据库里已经手动的插入了用户名“admin”``密码“111111”的数据。


@Service //标记这是一个service类
public class UserService {
    @Autowired //自动装配UserDAO对象
    UserDAO userDAO;
    /**
     * 判断用户是否存在,存在则返回true,不存在则返回false
     * @param username 用户名
     * @param password 用户密码
     * @return true,false
     */
    public boolean isUserExist(String username, String password) {
        List<User> userList = userList();
        boolean isExist = false;
        for (User user: userList) {
            if (user.getUsername().equals(username) && user.getPassword().equals(password)) {
                isExist = true;
            }
        }
        return isExist;
    }
}


4.Controller类UserController


这里就是调用了userService.isUserExist()判断用户是否在数据库的user表里.

存在的话,就返回一个code:20000 和一个写死的tokenadmin-token;

不存在的话就返回code :50000和一个错误信息“msg”


@RestController //标记这是控制器,下面每个方法的返回值都会直接转换成json数据格式
@RequestMapping("user")
public class UserController {
    @Autowired //自动装配 CategoryService
    UserService userService;
    @PostMapping("/login")
    public Map<String, Object> login(@RequestBody JSONObject data) throws Exception {
        String username = JSONPath.eval(data,"$.username").toString();
        String password = JSONPath.eval(data,"$.password").toString();
        Map<String, Object> result = new HashMap<>();
        Map<String, Object> userToken = new HashMap<>();
        Map<String, Object> msg = new HashMap<>();
        if (userService.isUserExist(username, password)) {
            userToken.put("token","admin-token");
            result.put("code", 20000);
            result.put("data", userToken);
        } else {
            msg.put("msg", "用户或密码错误");
            result.put("code", 50000);
            result.put("data", msg);
        }
        return result;
    }


三、登录-前端


1. api目录下的user.js


看过这个前端框架介绍你就知道了,要请求的后端API都是在这里写的,模块你自己分,好维护就行。


这里我的后端接口url就是/my_platform/user/login。 这个接口请求要提交的参数是usernamepassword


import request from '@/utils/request'
export function login(username, password) {
  return request({
    url: '/my_platform/user/login',
    method: 'post',
    data: { // 提交的数据
      username,
      password
    }
  })
}


2. store目录下的/modules/user.js


这里代码比较多,我只贴改动的地方。那就是actions里的login方法。


里面的login方法就是调用了上面api模块下的login ,其他地方的代码暂时未动,以实现本章目标为主。


login({ commit }, userInfo) { //定义 login 方法,在组件中使用 this.$store.dispatch() 调用
    const username = userInfo.username.trim()
    const password = userInfo.password
    return new Promise((resolve, reject) => {
      login(username, password).then(response => { //使用 login 接口进行网络请求
        const { data } = response
        commit('SET_TOKEN', data.token)
        setToken(data.token)
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  }


3. views目录下的/login/index.vue


上面template和下面style都没动,中间script 是重点。


其中,我注释掉了一些代码,因为这是项目里demo用的演示,必须用户名填admin。


但是我的目的是只要是数据库里有的,就可以登录,所以不要这个前端验证。


<script>
  import { validUsername } from '@/utils/validate'
  import { login } from '@/api/user'
  export default {
    name: 'Login',
    data() {
      // const validateUsername = (rule, value, callback) => {
      //   if (!validUsername(value)) {
      //     callback(new Error('Please enter the correct user name'))
      //   } else {
      //     callback()
      //   }
      // };
      // const validatePassword = (rule, value, callback) => {
      //   if (value.length < 6) {
      //     callback(new Error('The password can not be less than 6 digits'))
      //   } else {
      //     callback()
      //   }
      // };
      return {
        loginForm: {
          username: '',
          password: ''
        },
        // loginRules: {
        //   username: [{ required: true, trigger: 'blur', validator: validateUsername }],
        //   password: [{ required: true, trigger: 'blur', validator: validatePassword }]
        // },
        loading: false,
        passwordType: 'password',
        redirect: undefined
      }
    },
    watch: {
      $route: {
        handler: function(route) {
          this.redirect = route.query && route.query.redirect
        },
        immediate: true
      }
    },
    methods: {
      showPwd() {
        if (this.passwordType === 'password') {
          this.passwordType = ''
        } else {
          this.passwordType = 'password'
        }
        this.$nextTick(() => {
          this.$refs.password.focus()
        })
      },
      handleLogin() {
        this.$refs.loginForm.validate(valid => {
          if (valid) {
            this.loading = true
            this.$store.dispatch('user/login', this.loginForm).then(() => {
              this.$router.push({ path: this.redirect || '/' })
              this.loading = false
            }).catch(() => {
              this.loading = false
            })
          } else {
            console.log('error submit!!');
            return false
          }
        })
      }
    }
  }
</script>


handleLogin()就是对于登录的处理了, $store.dispatch会调用 /modules/user.js里的login()


四、验证登录功能


终于到了验证时刻了,我已经在数据库user表里添加了其他用户,所以我输入正确的用户名和密码就可以登录。

1268169-20200720194534888-1222174473.png


1268169-20200720194541561-670594450.png


登录成功。


1268169-20200720194556356-1343360858.png


当然了,不管是前端还是后端代码,我知道都埋了很多坑,也写的不规范,但是目前处于初级阶段,一步步来。


有错误的地方,也欢迎各位指出,谢谢!

相关文章
|
6月前
|
开发工具 数据安全/隐私保护 UED
Uniapp 微信登录流程解析
Uniapp 微信登录流程解析
205 0
|
存储 小程序 前端开发
微信小程序进阶——后台交互个人中心授权登录
微信小程序进阶——后台交互个人中心授权登录
182 0
|
存储 小程序 JavaScript
借助云开发实现小程序的登陆注册功能
借助云开发实现小程序的登陆注册功能
297 0
|
5月前
|
前端开发 Java 数据库
综合性练习(后端代码练习2)——用户登录
综合性练习(后端代码练习2)——用户登录
31 2
|
6月前
|
前端开发
基于Jeecgboot前后端分离的聊天功能集成(二)
基于Jeecgboot前后端分离的聊天功能集成(二)
101 0
|
6月前
|
前端开发 API
基于Jeecgboot前后端分离的聊天功能集成(一)
基于Jeecgboot前后端分离的聊天功能集成(一)
207 0
|
6月前
|
SQL 前端开发 API
前端登录流程
前端登录流程
119 0
|
存储 JSON 小程序
【小程序云开发】不用后端也能构建完整的微信小程序
本文介绍了如何从零开始学习和掌握微信小程序云开发,包括云函数、云数据库和HTTP触发等重要概念。通过详细的步骤和示例,读者将学会如何创建和部署云函数,以及如何使用云数据库来存储和管理小程序的数据。同时,本文还介绍了如何通过HTTP触发器实现小程序与外部API的数据交互,从而为小程序开发提供更灵活、高效的后端解决方案。无论您是初学者还是有一定经验的开发者,本文都将帮助您轻松掌握微信小程序云开发,并为您的小程序开发项目提供更多可能性。
1181 0
|
小程序 开发者
【轻松开发微信小程序】实现用户增删改查功能
本篇文章主要介绍如何从零开始开发微信小程序,并以实现用户增删改查功能为例,详细讲解了小程序的目录结构、项目创建、编码等方面。通过本文的学习,读者可以了解到微信小程序开发的基本流程和常见操作,为深入学习和实践提供了基础。
417 0
|
6月前
|
JSON 小程序 前端开发
史上最详细微信小程序授权登录与后端SprIngBoot交互操作说明!!!附源代码
史上最详细微信小程序授权登录与后端SprIngBoot交互操作说明!!!附源代码
1631 2
下一篇
无影云桌面