搜索
您的当前位置:首页正文

基于Node.js和Cocos Creator的开发 -实现用户

来源:知库网

一,重构用户创建

  • 定义用户名和用户ID映射键
    在constData.js中添加一行定义:
    'UNAME_UID_MAP_KEY' : 'uname:uid',
    此键值对应值的数据结构为hash,field为用户名,value为userId。
  • 重构创建用户函数
    在创建用户时首先检测是否已经存在用户名和用户ID的对应关系了,如果存在则此用户名不可用,不存在则创建用户,同时记录用户名和用户ID的对应关系。
    在user.js中重构createUser如下:
user.createUser = function(userName, passWord, callBack) {
    
    var createUser = function(userId) {
         // 获取到用户ID后创建用户
         var userKey = constData.USER_BASEK_KEY + userId;
         var userData = {
             'name' : userName,
             'passWord' : passWord,
             'coin' : 0,
             'diamond' : 0,
             'head' : '',
             'friends':[]
         }

        //  数据库创建用户
         redisDB.hmset(userKey, userData, function(err, result) {
             var data = {
                 'userId' : userId,
                 'name' : userName,
                 'token' : ''
             }

            //  创建用户名和id的映射
            redisDB.hset(constData.UNAME_UID_MAP_KEY, userName, userId);

             if(err) {
                data = {
                    'error' : err,
                    'note' : 'create user error!!'
                }
                callBack(data);
                return;
             }
             callBack(data);
         })
    }

    var getUserId = function() {
        redisDB.incrby(constData.GLOBAL_USER_ID, 1, function(err, userId) {
            if(err) {
                var data = {
                    'error' : err,
                    'note' : 'create user error!!'
                }
                callBack(data);
                return;
            }
    
            createUser(userId);
        });
    }

    // 检验用户名是否存在
    redisDB.hget(constData.UNAME_UID_MAP_KEY, userName, function(err, result) {
        if(result) {
            data = {
                'error' : 1,
                'note' : 'UserName exist'
            }
            callBack && callBack(data);
            return;
        }
        
        getUserId();
    });
}

这样,在登录的时候我们可以根据用户名找到用户ID,进而找到所有的用户信息。

二,开发前端登录功能

1, UI

登录UI包含以下几个控件:

  • 用户名输入框
  • 密码输入框
  • 登录按钮
  • 输入错误提示信息
    如下图所示:


    01.png
2,代码开发
  • 定义登录路径
    在Conatnt.js中加入以下定义:
    Constant.LOGIN_URL = baseURL + 'login/';
  • 登录逻辑开发
    在Script/Scene文件夹下新建login.js文件,首先引入文件:
var http = require('http');
var Constant = require('Constant');

定义相关变量引用:

passWordOrUserNameIsNull: {
    default: null,
    type: cc.Label
},
passWordErrorHint: {
    default: null,
    type: cc.Label
},
userName: '',
passWd: ''

在定义上相关变量后,在编辑器中进行变量和控件的对应关系操作。

进行输入用户名/密码完毕后的操作:

inputUserNameEnded: function(editbox, customEventData) {
    this.userName = editbox.string;
},

inputPassWordEnded: function(editbox, customEventData) {
    this.passWd = editbox.string;
},

再将其和编辑器中的控件对应起来。

实现输入错误时的提示函数:

_showErrorHint: function(label) {
    this.passWordErrorHint.node.active = false;
    this.passWordOrUserNameIsNull.node.active = false;

    // 显示提示
    label.node.active = true;

    // 设置计时器
    this.scheduleOnce(function(){
        label.node.active = false;
    }.bind(this), 2);
},

登录按钮测回调函数

onLogin: function() {
    if (!this.userName || this.userName.length<1) {
        console.log('onLogin come in 000');
        this._showErrorHint(this.passWordOrUserNameIsNull);
        return;
    }

    if (!this.passWd || this.passWd.length<1) {
        console.log('onLogin come in 001 this.passWd = ' + this.passWd);
        this._showErrorHint(this.passWordErrorHint);
        return;
    }

    this._startLogin();
},

将其和登录按钮对应起来。
登录函数的实现

_startLogin: function() {
    var obj = {
        'url' : Constant.LOGIN_URL,
        'data' : {
            'userName' : this.userName,
            'passWord' : this.passWd
        },
        'success' : function(jsonData) {
            this._onLoginSuccess(jsonData);
        }.bind(this),

        'fail' : function() {
            this._onLoginFail(jsonData);
        }.bind(this)

    }
    
    http.request(obj);
},

登录回调函数的实现
本次只把登录结果信息打印出来:

_onLoginSuccess: function(jsonData) {
    console.log('_onLoginSuccess come in jsonData = ' + JSON.stringify(jsonData));
},

_onLoginFail: function(jsonData) {
    console.log('_onLoginFail come in jsonData = ' + JSON.stringify(jsonData));
},

三,后端功能实现

1,实现生成token功能
在constData.js中添加用户ID和token映射的键:
'USER_TOKEN_KEY' : 'uid:token'
此键对应的值为hash,field为用户ID,值为用户的token。
我们的token使用一组随机数加用户ID和时间等信息组成:

var randomInt = function() {
    return Math.ceil(Math.random() * 9999999);
}

var formatDate = function() {
    var d = new Date();
    return d.getFullYear() + '-' + d.getMonth() + '-' + d.getDay() + ' ' + d.getHours()+':'+d.getMinutes()+':'+d.getSeconds() + ' ' + d.getMilliseconds();
}

var setToken = function(userId) {
    var token = '' + randomInt() + '|' + userId + '|' + randomInt() + '|' + formatDate() + '|' + randomInt();
    redisDB.hset(constData.USER_TOKEN_KEY, userId, token);
    return token;
}

2,实现用户登录逻辑
在用户登录时我们后端需要做的事:

  • 根据用户名找到用户ID
  • 根据用户ID找到用户信息
  • 判断用户输入的密码和找到的用户信息中存储的用户密码是否一致
  • 返回结果
    在user.js文件中添加入如下函数
user.login = function(userName, passWord, callBack) {
    redisDB.hget(constData.UNAME_UID_MAP_KEY, userName, function(err, result) {
        if(!result) {
            data = {
                'error' : 1,
                'note' : 'UserName not exist'
            }
            callBack && callBack(data);
            return;
        }

        // 获取用户
        var userKey = constData.USER_BASEK_KEY + result;
        var dataElements = ['passWord', 'name', 'coin', 'diamond', 'head', 'friends'];
        redisDB.hmget(userKey, dataElements, function(err, result) {
            if (err) {
                var data  = {
                    'error' : 1,
                    'note' : 'get userinfo error!'
                }
                callBack && callBack(data);
                return;
            }

            //判断用户密码是否相同
            var userData = {};
            for(var i=0, l=dataElements.length; i<l; i++) {
                userData[dataElements[i]] = result[i];
            }
            // 设置用户token
            userData['token'] = setToken(result);

            if(userData['passWord'] == passWord) {
                var data = {
                    'error' : 0,
                    'data' : userData
                }
                callBack && callBack(data);
                return;
            }
            data = {
                'error' : 1,
                'note' : 'Error password'
            }
            callBack && callBack(data);
        });
    });
}

3,路由映射
在router.js中添加登录功能的处理:

router.login = function(req, res, callBack) {
    var params = getParams(req);
    //登录
    user.login(params['userName'], params['passWord'], function(data) {
        callBack && callBack(data);
    })
}

至此,我们就完成了用户登录过程。



Top