leancloud 用户系统

2,539 阅读5分钟

对于nodejs开发者来说,可能会发现leancloud有两个给js使用的sdk:leanengine-node-sdkjavascript-sdk
前者的npm包名是leanengine,后者包名叫做avoscloud-sdk。
看一下leanengine的package.json可以发现



leanengine是依赖avoscloud-sdk的,leanengine除了能够使用avoscloud-sdk的全部功能以外,还有额外拓展的供nodejs使用的方法。

所以结论就是,如果是一个纯前端的项目,就引入avoscloud-sdk,而如果使用在nodejs服务器的话,则引入leanengine。之前有一个项目在(我猜是因为)前端使用了leanengine,会使chrome产生websocket连接的问题,而导致浏览器卡死。
用户


在leancloud新建的项目,会有6个默认的Class,这篇文章会说到其中的_User

_User表的字段如下:



其中username和password是必填字段,而且username是一个要求唯一的字段。email和mobilePhoneNumber则是选填字段。

authData用来保存第三方登录信息,也是本文后面重点要说的部分。

emailVerified和mobilePhoneVerified是布尔型,用来标注邮箱和手机是否验证。顺便一提,邮箱验证和手机验证服务已经集成在leancloud内了,不需要使用额外的邮件或短信服务商,而且验证后直接更新数据库,完全没有开发的成本。

sessionToken字段是记录用户会话的,在avoscloud-sdk 0.5.1版本中,加入了AV.User.become方法,可以使用sessionToken直接登录。

注册 AV.User.signUp()

LeanCloud 文档
标注的注册方法需要用户名和密码,其他信息可以随注册信息一起提供,或者在signUp的回调中再次更新。

登录 AV.User.logIn()

LeanCloud 文档
leancloud的标准登录方法除了支持username和password登录,同时支持email和password登录。这也就是说,邮箱登陆的功能也不需要额外开发了,可以直接在登录框位置注明:“用户名/邮箱” 然后无论用户输入的是username还是email,都可以用logIn方法登入。

如果要使用手机登录,则要调用AV.User.logInWithMobilePhone()方法,另一种手机登录方式是通过手机号和验证短信直接登入的AV.User.requestSmsCode(),如果使用这个方法注册的话,新用户的username默认为手机号码。

绑定第三方

LeanCloud 文档**
AV.User._logInWith()方法提供了第三方绑定的方法。这个方法会创建一个新的用户,username为随机串。

绑定微博的代码是:

AV.User._logInWith('weibo', { 
    'authData': {
        'uid': '123456789', 
        'access_token': '2.00vs3XtCI5FevCff4981adb5jj1lXE', 'expiration_in': '36000' 
    }
}).then(function(user) { 
    //返回绑定后的用户 
    console.log(user);
},
function(error) { 
    console.log(error);
});

绑定github可以用:

AV.User._logInWith('github',{ 
    "authData":{ 
        'uid': uid, 
        'access_token': access_token 
    }
}).then(function(user) { 
    console.log(user)
}, 
function(error) { 
    console.log(error);
});

其中微博,微信和QQ,leancloud会在登录时验证access_token的可靠性,其他第三方平台要自行通过平台的方法去验证。
如果已经有一个leancloud账号,想要绑定第三方,可以使用_linkWith方法

var user = ...已存在的处于登录状态的 AV.User 对象 ...
user._linkWith('weibo', { 
    'authData': { 
        'uid': '123456789', 
        'access_token': '2.00vs3XtCI5FevCff4981adb5jj1lXE', 
        'expiration_in': '36000' 
    }
}).then(function(user) { 
    console.log(user);
}, function(error) { 
    console.log(error);
});

这里leancloud不会验证这个第三方账号是不是已经被其他用户绑定,如果同一个微博账号多次绑定用户,代码执行的时候不会报错,在登录的时候,会登入最后一个绑定的账号。

当前用户

通过AV.User.current()方法可以得到当前登录的用户。这里面就要说一下前端登录和后端登录的关系。

后端登录和前端是分开的,比如做第三方登录的时候,第三方都需要一个回调地址,那么我们可以在这个回调的路由中处理accesstoken的验证,然后(也必须)在后端完成登录。这个部分不能做在前端,因为验证accesstoken需要第三方的appid和secretid,secretid是不能够暴露在前端的。

那么在后端调用了比如AV.User._logInWith()方法完成登录之后,同样可以用AV.User.current()取到用户信息。

leancloud提供了session和cookie管理的中间件

app.use(AV.Cloud.CookieSession({ secret: 'xitusecretxxxx', maxAge: 3600000, fetchUser: false }));
引入这个中间件之后,当后台登录,前端请求的页面都会带有一个cookie(截图是未登录状态)


cookie的默认名是avos:sess
注意这个cookie是而且只能是httpOnly的。
当页面发出HTTP请求到路由(以express代码为例)

function adminIsLoggedIn(req, res, next) { 
    var user = req.AV.user; 
    if(!user) 
        return res.redirect('/'); 
    var query = new AV.Query(AV.Role);
    query.equalTo('users', user); 
    query.equalTo('name', "admin"); 
    query.count().then(function(count){ 
        if(count) { 
            return next(); 
        } 
        else
            { 
                return res.redirect('/'); 
            } 
        }, function(error) { 
            return res.redirect('/'); 
        });
}
app.get('/admin', adminIsLoggedIn, admin.home);

req.AV.user能够得到当前session中的user对象,从而进行身份验证。leancloud官方不建议在这里使用AV.User.Current(),因为这个函数使用了Domain。另外要注意的是,如果仅仅使用了前端登录,那么虽然在前端可以AV.User.Current()拿到user,但是req.AV.user依然是空的。

前端登录就比较简单了,同样调用登录函数,leancloud会把个人信息放在localstorage里面


然后前端调用AV.User.current()就可以取到当前的的用户信息。

一般的应用应该使用后端登录的方式,而如果是微信移动端或者是SPA的应用,可以考虑前端登录方式。

OAuth2

既然前面说到了第三方登录,顺便说说OAuth2。


一个比较通用的OAuth2过程如上图所示,不同平台的参数个数和参数名可能略有不同,就把几个重要的参数拿出来说明一下。

首先是请求授权页面,需要第三方平台的appid,回调地址要提前在第三方注册,scope是请求的权限,state是可以在授权成功之后返回的参数。

授权成功之后,返回授权页面,可以通过传入的state来决定不同的方式,比如多个平台共用一个回调地址的时候,可以通过state参数来判断code所属平台,然后调用对应平台的验证API。

通过code换取access_token这一步必须要在后台完成,因为涉及到使用appsecret,不能暴露在前端。
得到access_token之后,就可以为所欲为的拿用户各种数据啦。