作者:王德福@稀土
对于 Node.JS 开发者来说,可能会发现 LeanCloud 有两个给 js 使用的 SDK:LeanEngine-node-sdk和 JavaScript-SDK,前者的 npm 包名是 leanengine,后者包名叫做 avoscloud-sdk。
看一下LeanEngine 的 package.json 可以发现
LeanEngine 是依赖 avoscloud-sdk 的,LeanEngine 除了能够使用 avoscloud-sdk 的全部功能以外,还有额外拓展的供 Node.JS 使用的方法。
所以结论就是,如果是一个纯前端的项目,就引入 avoscloud-sdk,而如果使用在 Node.JS 服务器的话,则引入 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 登录,同时支持 emai l和 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 之后,就可以为所欲为的拿用户各种数据啦。