用户的注册和微信授权

为了追求快速上线,项目组决定,去掉传统项目中的“用户注册”, “用户登录”, 直接使用微信的账户来核对。

  1. 用户的微信浏览器带着当前微信用户的open_id,跳转到“后台服务器”。
  2. “后台服务器” 给“微信服务器” 发送请求。 获得当前微信用户的信息
  3. “后台服务器” 为该用户生成一个用户文件
  4. “后台服务器” 告知“H5端” 已经成功注册该用户。
  5. “H5端” 为该用户展示对应的页面。

如下图所示:

用户注册过程

可以看出, 主要代码都是在 服务器端。

1. 让微信用户打开首页后,直接跳转到后台服务器

1.1 修改对应的路由文件(src/router/index.js):

  1. Vue.use(Router)
  2. export default new Router({
  3. routes: [
  4. {
  5. path: '/wait_to_shouquan',
  6. name: 'wait_to_shouquan',
  7. component: require('../views/wait_to_shouquan.vue')
  8. },
  9. ]
  10. })

1.2 增加对应的vue(src/views/wait_to_shouquan.vue) :

  1. <template>
  2. <div style="padding: 50px;">
  3. <h3>正在跳转到授权界面...</h3>
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. created () {
  9. window.location.href = this.$store.state.web_share + "/auth/wechat"
  10. },
  11. components: {
  12. }
  13. }
  14. </script>

可以看到, 上面的代码中, 使用到了 Vuex 来保存系统变量(后台服务器的地址) .

1.3 增加核心模板文件(src/main.vue) :

  1. <template>
  2. <div id="app">
  3. <router-view></router-view>
  4. </div>
  5. </template>
  6. <script>
  7. import store from './vuex/store'
  8. import { SET_BASEINFO, GET_BASEINFO } from './vuex/mutation_types'
  9. export default {
  10. store,
  11. name: 'app',
  12. data () {
  13. return {
  14. user_info: {
  15. open_id: this.$route.query.open_id
  16. }
  17. }
  18. },
  19. mounted () {
  20. // TODO 开发环境下使用, 生产环境下注释掉
  21. // store.dispatch(SET_BASEINFO, {open_id: 'opFELv6YkJkMaH-xFkokTWCs5AlQ'})
  22. if (this.user_info.open_id) {
  23. store.dispatch(SET_BASEINFO, this.user_info)
  24. } else {
  25. store.dispatch(SET_BASEINFO)
  26. if (store.state.userInfo.open_id === undefined) {
  27. console.info('用户id和open_id不存在, 跳转到授权等待页面')
  28. this.$router.push({name: 'wait_to_shouquan'})
  29. } else {
  30. console.info('已经有了BASEINFO')
  31. }
  32. }
  33. },
  34. watch: {
  35. '$route' (val) {
  36. }
  37. },
  38. methods: {
  39. },
  40. components:{
  41. }
  42. }
  43. </script>
  44. <!-- 下方的 CSS 略过 -->

可以看到, 上面代码的 mounted() 方法中, 会对 当前用户的open_id 进行判断. 如果存在,调到首页。 如果不存在,表示该用户是新用户。 需要跳转到授权等待页面。对应的代码如下所示:

  1. if (this.user_info.open_id) {
  2. store.dispatch(SET_BASEINFO, this.user_info)
  3. } else {
  4. store.dispatch(SET_BASEINFO)
  5. if (store.state.userInfo.open_id === undefined) {
  6. console.info('用户id和open_id不存在, 跳转到授权等待页面')
  7. this.$router.push({name: 'wait_to_shouquan'})
  8. } else {
  9. console.info('已经有了BASEINFO')
  10. }
  11. }

1.4 增加对应的Vuex代码

目前来看, Vuex需要保存2个信息:

  • 用户的open id
  • 远程服务器的地址,端口等常量.

1.4.1 增加 src/vuex/store.js . 这个是最最核心的文件。 完整如下所示:

  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. import userInfo from './modules/user_info'
  4. import tabbar from './modules/tabbar'
  5. import toast from './modules/toast'
  6. import countdown from './modules/countdown'
  7. import products from './modules/products'
  8. import shopping_car from './modules/shopping_car'
  9. import * as actions from './actions'
  10. import * as getters from './getters'
  11. Vue.use(Vuex)
  12. Vue.config.debug = true
  13. const debug = process.env.NODE_ENV !== 'production'
  14. export default new Vuex.Store({
  15. state: {
  16. web_share: 'http://shopweb.siwei.me',
  17. h5_share: 'http://shoph5.siwei.me/?#'
  18. },
  19. actions,
  20. getters,
  21. modules: {
  22. products,
  23. shopping_car,
  24. userInfo,
  25. tabbar,
  26. toast,
  27. countdown
  28. },
  29. strict: debug,
  30. middlewares: debug ? [] : []
  31. })

上面的代码中, 部分代码是在后面会陆续用到的。 我们不用过多考虑。 只需要关注下面几行:

  1. export default new Vuex.Store({
  2. // 这里定义了若干系统常量
  3. state: {
  4. web_share: 'http://shopweb.siwei.me',
  5. h5_share: 'http://shoph5.siwei.me/?#'
  6. },
  7. modules: {
  8. // 这里定义了 当前用户的各种信息, 我们把它封装成为一个js对象
  9. userInfo,
  10. },
  11. })

1.4.2 增加vuex/modules/user_info.js 这个文件:

  1. import {
  2. SET_BASEINFO,
  3. CLEAR_BASEINFO,
  4. GET_BASEINFO,
  5. COMMEN_ROLE,
  6. GET_BGCOLOR,
  7. GET_FONTCOLOR,
  8. GET_BORDERCOLOR,
  9. GET_ACTIVECOLOR,
  10. EXCHANGE_ROLE
  11. } from '../mutation_types'
  12. const state = {
  13. id: undefined, //用户id
  14. open_id: undefined, // 用户open_id
  15. role: undefined
  16. }
  17. const mutations = {
  18. //设置用户个人信息
  19. [SET_BASEINFO] (state, data) {
  20. try {
  21. state.id = data.id
  22. state.open_id = data.open_id
  23. state.role = data.role
  24. } catch (err) {
  25. console.log(err)
  26. }
  27. },
  28. //注销用户操作
  29. [CLEAR_BASEINFO] (state) {
  30. console.info('清理缓存')
  31. window.localStorage.clear()
  32. },
  33. }
  34. const getters = {
  35. [GET_BASEINFO]: state => {
  36. console.info('进入到了getter中了')
  37. let localStorage = window.localStorage
  38. let user_info
  39. if (localStorage.getItem('SLLG_BASEINFO')) {
  40. console.info('有数据')
  41. user_info = JSON.parse(localStorage.getItem('SLLG_BASEINFO'))
  42. } else {
  43. console.info('没有数据')
  44. }
  45. return user_info
  46. },
  47. [COMMEN_ROLE]: state => {
  48. if (state.role === 'yonghu') {
  49. return true
  50. } else {
  51. return false
  52. }
  53. },
  54. }
  55. const actions = {
  56. [SET_BASEINFO] ({ commit, state }, data) {
  57. //保存信息
  58. if (data !== undefined) {
  59. let localStorage = window.localStorage
  60. localStorage.setItem('BASEINFO', JSON.stringify(data))
  61. commit(SET_BASEINFO, data)
  62. } else {
  63. if (localStorage.getItem('BASEINFO')) {
  64. data = JSON.parse(localStorage.getItem('BASEINFO'))
  65. commit(SET_BASEINFO, data)
  66. } else {
  67. }
  68. }
  69. }
  70. }
  71. export default {
  72. state,
  73. mutations,
  74. actions,
  75. getters
  76. }

该文件定义了用户的信息的各种属性。

1.4.3 增加 src/vuex/mutation_types.js

  1. export const SET_BASEINFO = 'SET_BASEINFO'
  2. export const GET_BASEINFO = 'GET_BASEINFO'

上面内容定义了该对象的两个操作。

1.4.4 增加 src/vuex/modules/actions.js

  1. import * as types from './mutation_types'

可以看到上面的内容对于 mutation_types 进行了引用。

1.4.5 增加 src/vuex/modules/getters.js

  1. // 先放成空内容好了

这个文件先这样存在,目前阶段不需要有任何内容。

1.5 与后台的对接

后台的同学, 为我们提供了一个链接入口:

http://shopweb.siwei.me/auth/wechat

我们让H5页面直接跳转过去就可以。 这里不需要加任何参数, 直接由后端的同学搞定接下来的事情。

查看效果

在微信开发者工具中,打开我们的H5 页面, 就会看到页面会自动跳转.

观察仔细的同学可以看到有两次跳转:

第一次跳转到 http://shopweb.siwei.me/auth/wechat第二次跳转到 https://open.weixin.qq.com/connect/oauth2/authorize

如下图所示:

微信授权页面

点击“确认登录”按钮,进行授权后,就会进入到H5的首页

总结

本节中,为了做一件事: 让用户跳转到微信授权,并注册, 我们做了如下的程序层面的内容:

  • 使用Vuex 记录系统常量(远程服务器的地址)
  • 使用Vuex 记录用户的信息(新增了一个对象:user_info)
  • 使用了一个独立的页面(等待微信授权页面)
  • 每次打开首页之前,都要判断该用户是否登录。
  • (后台任务) 让该用户在微信端授权, 并且在本地生成一个新的用户, 然后把相关数据返回给前端

Vuex 是Vuejs 最复杂最不好理解的地方。 同学们不要怕。 之所以这么麻烦, 可以认为是javascript的语言特性决定的。 就好像java, C语言中大量用到的设计模式, 在现代编程语言(Ruby , Python, Perl)中就用不到, 可以有更加简单的办法, 例如Mixin)

另外,本节对于后端的同学是个挑战, 不但要在微信端做修改,还需要对微信返回的数据结构很熟悉。 由于本书内容所限,不再赘述。