对于想了解在RestAPI中使用Facebook为Express和NodeJS中的JWT维护秘密密钥和访问令牌的读者,本文将提供新的信息,我们将详细介绍restforapi,并且为您提供关于4.4权限
对于想了解在Rest API中使用Facebook为Express和NodeJS中的JWT维护秘密密钥和访问令牌的读者,本文将提供新的信息,我们将详细介绍rest for api,并且为您提供关于4.4 权限拦截控制\AccessToken jwt-博客后端Api-NodeJs+Express+Mysql实战、android – Facebook SDK 3.0 – 获取Facebook用户名和访问令牌、angularjs – 保存密钥和访问令牌在快速和NodeJS与Facebook的Rest API中的JWT、asp.net – MVC 5 Web API与Facebook访问令牌到RegisterExternal而不需要Cookie的有价值信息。
本文目录一览:- 在Rest API中使用Facebook为Express和NodeJS中的JWT维护秘密密钥和访问令牌(rest for api)
- 4.4 权限拦截控制\AccessToken jwt-博客后端Api-NodeJs+Express+Mysql实战
- android – Facebook SDK 3.0 – 获取Facebook用户名和访问令牌
- angularjs – 保存密钥和访问令牌在快速和NodeJS与Facebook的Rest API中的JWT
- asp.net – MVC 5 Web API与Facebook访问令牌到RegisterExternal而不需要Cookie
在Rest API中使用Facebook为Express和NodeJS中的JWT维护秘密密钥和访问令牌(rest for api)
我有两个应用程序:
- server ( REST API Server)
- node js
- Express
- jsonwebtokens
- express-jwt
- mongoose
- client (Portable Front-end)
- bootstrap
- Angular JS
- local-storage
- angular-facebook
- angular-jwt
稍后,客户端应用程序将使用phonegap移植到android,iphone和其他平台。对于OAuth,我使用Facebook作为提供者。现在,我刚刚意识到JSON
Web令牌是进行这种设置的方法。我的问题是体系结构的而不是语法的-在nodejs中用JWT对Facebook访问令牌和用户ID签名时如何管理密钥?
所以这是流程在我的应用程序中的工作方式:
- Angular 客户端 有一个登录按钮
- 用户单击按钮> Facebook身份验证开始
- 客户端 收到user_id和FB访问令牌
- 客户端 将[ POST json正文 ] user_id和访问令牌都发送到位于 “ http://server.com/auth/login ”的 Node + Express Server 。
- 节点服务器* 已将express-jwt应用于除 / auth / login 之外的所有路由,并带有一个 *
var expressJwt = require(’express-jwt’);
var jwt = require(’jsonwebtoken’);
app.use(expressjwt({secret:’‘})。unless({path:[‘/ auth / login’]})));
- 节点服务器 从 req.body 接收数据,使用JavascriptSDK从facebook获取所有配置文件详细信息,并使用对其进行签名
var token = expressjwt.sign({profile},);
- 节点服务器 将新令牌存储(更新,如果存在user_id)在db中,并将其作为响应发送给 客户端
- 客户端 将接收到的新令牌作为json数据存储在本地存储中
- 客户端使用angular-jwt 从新令牌中获取配置文件数据,并将新令牌自动附加到它发送给服务器的所有请求的Authorization标头中
现在,我的问题是:
- 我真的需要将JWT令牌存储在数据库中吗?我当然没有将请求标头中的令牌与数据库进行比较
- 每次有人登录时,我是否需要生成随机密钥以确保安全性?如果是的话,那么这将在客户端和服务器中都适用吗?
- 我需要何时何地检查令牌到期?以及如何刷新它?
我有点迷失设计流程和机制。
答案1
小编典典广告1.您不必将JWT存储在数据库中。用户ID可以是有效负载的一部分,因此不需要它。
广告2。服务器端应用程序通常使用一个密钥来生成所有JWT。
广告3.检查对您的API的每次请求令牌是否已过期,如果令牌已过期则不允许访问,请返回401状态代码。客户端应用应提示用户输入凭据并请求新的JWT。如果要避免用户重新提交凭据,则可以发出刷新令牌,该刷新令牌以后可用于生成新的JWT。
http://bitoftech.net/2014/07/16/enable-oauth-refresh-tokens-angularjs-app-
using-asp-net-web-api-2-owin/
4.4 权限拦截控制\AccessToken jwt-博客后端Api-NodeJs+Express+Mysql实战
权限控制
业务需求:查看用户列表接口(管理员才能使用)、更新用户信息接口(当前对应用户才能调用)
这时候需要需要加入中间件来实现权限控制:
这时候咱们需要学习了解下 :AccessToken jwt
AccessToken jwt
课前学习了解
JSON Web Token 入门教程
http://www.ruanyifeng.com/blo...
基于jsonwebtoken(JWT) 的web认证 (Node版实现)
https://segmentfault.com/a/11...
node-jsonwebtoken
https://github.com/auth0/node...
本文中使用了node-jsonwebtoken@7.2.1插件
现将token服务逻辑代码附上
/**
* token服务
* add by boomer 2019-05-03 21:57:11
*/
var Promise = require("bluebird");
var config = require(''config-lite''); //配置
var jwt = require(''jsonwebtoken''); //json token
module.exports = {
/**
* 设置token 创建token
*/
setToken: function(payload) {
// var expiresIn = Math.floor(Date.now() / 1000) + (1 * 60); // var expiresIn = ''24h'';
var expiresIn = Date.now() + 3600000 * 24;//24小时后
var token = jwt.sign(payload, config.token.secretOrPrivateKey, {
expiresIn: expiresIn, // 设置过期时间
});
return {
token: token,
expiresIn: expiresIn,
};
},
/**
* 验证token是否正确:传入当前token和当前用户uuid
*/
verifyToken: function(token, userUuid){
return new Promise(function(resolve, reject) {
jwt.verify(token, config.token.secretOrPrivateKey, function(err, tokenData) {
if (tokenData && tokenData.uuid == userUuid) {
resolve(''ok'');
}else{
reject(''fail'');
}
});
});
},
/**
* 路由验证token
*/
verifyRouterToken: function(req, res, next, isAdmin) {
//accesstoken 被自动转小写了
var token = req.headers.accesstoken;
if (!token) { // 如果没有token,则返回错误
res.json({
code: "401",
});
return;
} else { //验证token
jwt.verify(token, config.token.secretOrPrivateKey, function(err, tokenData) { //只有在token正确时tokenData有值
if (err) {
res.json({
code: "402",
});
return;
} else {
//验证是否为管理员
if (isAdmin && !tokenData.isAdmin) {
res.json({
code: "403",
});
return;
} else if (!isAdmin && tokenData.uuid && !tokenData.isAdmin) {
//验证userUuid 避免普通用户登录修改其他人资料
var userUuid = (req.body || req.query || req.params)[''userUuid''];
if (userUuid && userUuid != tokenData.uuid) {
res.json({
code: "403",
});
return;
} else {
next();
}
} else {
next();
}
}
});
}
},
/**
* 清除token
*/
delToken: function(token) {
if (!token) {
return ''delTokenFail'';
} else {
jwt.decode(token);
return ''delTokenSuccess'';
}
},
};
accessToken一般在登录/注册成功时获取 然后缓存到本地,每次前端请求时将有效的accessToken放到headers中(这块后面写前端时补充 更新token心跳机制等),然后请求到后端,后端再通过校验token中间件做权限拦截,校验通过后才能执行后面的业务逻辑
现在说下,后端通过上面tokenService.setToken方法 生成AccessToken的代码:
android – Facebook SDK 3.0 – 获取Facebook用户名和访问令牌
我正在跟随facebook本地登录 – http://developers.facebook.com/docs/tutorials/androidsdk/3.0/scrumptious/authenticate/
我使用Session.getAccesstoken获取访问令牌,我得到一些访问令牌,但是这是无效的.实际程序是什么?我做错了吗
如何使用Facebook SDK 3.0在Native登录中获取UserId
解决方法
final Session session = Session.getActiveSession(); if (session != null && session.isOpened()) { // If the session is open,make an API call to get user data // and define a new callback to handle the response Request request = Request.newMeRequest(session,new Request.GraphUserCallback() { @Override public void onCompleted(GraphUser user,Response response) { // If the response is successful if (session == Session.getActiveSession()) { if (user != null) { user_ID = user.getId();//user id profileName = user.getName();//user's profile name userNameView.setText(user.getName()); } } } }); Request.executeBatchAsync(request); }
user_ID& profileName是字符串.
对于accesstoken:
String token = session.getAccesstoken();
EDITED:(13/1/2014)
对于用户电子邮件(我没有通过在设备或模拟器上运行来检查此代码):
这些只是我的意见,或者你可以称之为建议
setReadPermissions(Arrays.asList("email",...other permission...)); //by analyzing the links bellow,i think you can set the permission in loginbutton as: loginButton.setReadPermissions(Arrays.asList("email",...other permission...)); user.asMap().get("email");
更多信息请看:
link1,link2,link3,link4,
angularjs – 保存密钥和访问令牌在快速和NodeJS与Facebook的Rest API中的JWT
>服务器(REST API服务器)
>节点js
>快递
> jsonwebtokens
> express-jwt
>猫鼬
>客户端(便携式前端)
>引导
>角度JS
>本地存储
角色facebook
> angle-jwt
后来,客户端应用程序将被移植到android,iphone和其他平台使用phonegap.对于OAuth,我正在使用Facebook作为提供者.现在,我刚才发现JSON Web Token是这种设置的方式.我的问题是架构性的,而不是语法的 – 如何在nodejs中使用JWT签署Facebook访问令牌和用户ID时如何管理密钥?
所以这是流程如何在我的应用程序中工作:
角度客户端有一个登录按钮
>用户点击按钮> Facebook Auth开始
>客户端接收user_id和FB访问令牌
>客户端将[POST json body]将user_id和访问令牌发送到Node Express Server为’http://server.com/auth/login‘
> Node Server已将express-jwt应用于除auth / login之外的所有路由
var expressJwt = require(‘express-jwt’);
var jwt = require(‘jsonwebtoken’);
app.use(expressjwt({secret:”})),({path:[‘/ auth / login’]}));
>节点服务器从req.body接收数据,使用JavascriptSDK从Facebook获取所有配置文件的详细信息,并使用它进行签名
var token = expressjwt.sign({profile},);
> Node Server存储(更新,如果user_id存在)db中的新令牌,并将其作为响应发送给客户端
>客户端将本地接收的新令牌作为json数据存储在本地存储中
>客户端使用angular-jwt从新令牌获取配置文件数据,并将其发送到服务器的所有请求自动附加到授权头中的新令牌
现在我的问题是:
>我真的需要在数据库中存储JWT令牌吗?我肯定不会将请求标头中的令牌与数据库进行比较
>我需要为安全性生成随机秘密密钥,每次登录?如果是,那么如何适应客户端和服务器?
>何时何地需要检查令牌过期?和如何刷新它?
我对设计流程和机制感到失落.
广告2.服务器端应用程序通常使用一个密钥来生成所有JWT.
广告3.检查您的API的每个请求上的令牌是否过期,如果令牌已过期,则不允许访问,返回401状态代码.客户端应用程序应提示用户获取凭据并请求新的JWT.如果要避免用户重新提交凭据,您可以发出刷新令牌,以后可以用于生成新的JWT.
JWT refresh token flow
http://bitoftech.net/2014/07/16/enable-oauth-refresh-tokens-angularjs-app-using-asp-net-web-api-2-owin/
asp.net – MVC 5 Web API与Facebook访问令牌到RegisterExternal而不需要Cookie
新的MVC5项目只用Web API.添加了Facebook AppId和Secret.
通过传入UserName和Password,我可以从Token端点获取我的Web API的Token.然后使用该令牌进行进一步的呼叫.
但
我想在iOS应用程序的Facebook SDK的帮助下注册新用户.
我正在使用Facebook SDK获取访问令牌. (假设在这一点上,我有一个访问令牌).
接下来我知道的是通过将该令牌传递给具有承载[访问令牌]的授权头部,但是会导致500个服务器错误,从而调用api / Account / RegisterExternal端点.
我想我知道的原因,Cookie缺失.我用Fidler的一个cookie做了同样的电话,它的工作. (通过转到ExternalLogins端点提供的URL接收Cookie).
由于cookie缺少等待Authentication.GetExternalLoginInfoAsync();在RegisterExternal操作内返回null.
// POST api/Account/RegisterExternal [OverrideAuthentication] [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)] [Route("RegisterExternal")] public async Task<IHttpActionResult> RegisterExternal(RegisterExternalBindingModel model) { if (!ModelState.IsValid) { return BadRequest(ModelState); } var info = await Authentication.GetExternalLoginInfoAsync(); if (info == null) { return InternalServerError(); } var user = new ApplicationUser() { UserName = model.Email,Email = model.Email }; IdentityResult result = await UserManager.CreateAsync(user); if (!result.Succeeded) { return GetErrorResult(result); } result = await UserManager.AddLoginAsync(user.Id,info.Login); if (!result.Succeeded) { return GetErrorResult(result); } return Ok(); }
我不想对我的Web API进行3次调用,要求外部登录,然后转到该URL并在Web浏览器中进行身份验证,以访问Facebook访问令牌,然后使用我需要收集的访问令牌和Cookie调用RegisterExternal端点在这些电话之间.
正如我所说,除了Facebook Ids,我没有改变任何模板.仍然代码如下.
public partial class Startup { public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; } public static string PublicclientId { get; private set; } // For more information on configuring authentication,please visit http://go.microsoft.com/fwlink/?LinkId=301864 public void ConfigureAuth(IAppBuilder app) { // Configure the db context and user manager to use a single instance per request app.CreatePerOwinContext(ApplicationDbContext.Create); app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); // Enable the application to use a cookie to store information for the signed in user // and to use a cookie to temporarily store information about a user logging in with a third party login provider app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); // Configure the application for OAuth based flow PublicclientId = "self"; OAuthOptions = new OAuthAuthorizationServerOptions { TokenEndpointPath = new PathString("/Token"),Provider = new ApplicationOAuthProvider(PublicclientId),AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),AccesstokenExpireTimeSpan = TimeSpan.FromDays(14),AllowInsecureHttp = true }; // Enable the application to use bearer tokens to authenticate users app.USEOAuthBearerTokens(OAuthOptions); app.UseFacebookAuthentication( appId: "xxxxxxxxxxxxxxx",appSecret: "xxxxxxxxxxxxxxxxxxxxxxxx"); } }
据我所知,Web API不需要Cookie,当我从令牌端点获得本地令牌,但为什么在执行ExternalRegister时首先需要Cookie
WebApiConfig类看起来像这样,不应该config.SuppressDefaultHostAuthentication();避免任何Cookie的需求
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API configuration and services // Configure Web API to use only bearer token authentication. config.SuppressDefaultHostAuthentication(); config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi",routeTemplate: "api/{controller}/{id}",defaults: new { id = RouteParameter.Optional } ); } }
我不知道我是否在这里错过了这一点.我的意图是不需要在本机iOS应用程序中使用Web浏览器进行令牌.那就是Facebook SDK获取访问令牌,并使用该调用RegisterExternal获取本地令牌并创建该用户身份.
我做了我的功课,我坚持这个想法.
思想赞赏!
解决方法
它不直接接受任何外部令牌.
事情是.. MVC 5正在为我们照顾一切,即从社会媒体收集令牌并验证/处理它.之后,它生成一个本地令牌.
RegisterExternal方法还需要维护Cookie,解决方案不会.
我写了一个blog post,这将详细解释.在下面添加了直接的答案.我的目标是使其融合并成为默认MVC Web API的登录/注册流程的组成部分,以确保其易于理解.
在下面的解决方案之后,授权属性必须如下才能工作,否则您将获得未经授权的响应.
[Authorize] [HostAuthentication(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ExternalBearer)] [HostAuthentication(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie)]
如果要仅允许令牌使用API,请使用ExternalBearer,如果要仅允许记录的Cookie使用API即从网站使用ApplicationCookie.如果您要允许两者的API,用户都可以.
将此操作添加到AccountController.cs
// POST api/Account/RegisterExternalToken [OverrideAuthentication] [AllowAnonymous] [Route("RegisterExternalToken")] public async Task<IHttpActionResult> RegisterExternalToken(RegisterExternalTokenBindingModel model) { if (!ModelState.IsValid) { return BadRequest(ModelState); } ExternalLoginData externalLogin = await ExternalLoginData.FromToken(model.Provider,model.Token); if (externalLogin == null) { return InternalServerError(); } if (externalLogin.LoginProvider != model.Provider) { Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie); return InternalServerError(); } ApplicationUser user = await UserManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider,externalLogin.ProviderKey)); bool hasRegistered = user != null; ClaimsIdentity identity = null; IdentityResult result; if (hasRegistered) { identity = await UserManager.CreateIdentityAsync(user,OAuthDefaults.AuthenticationType); IEnumerable<Claim> claims = externalLogin.GetClaims(); identity.AddClaims(claims); Authentication.SignIn(identity); } else { user = new ApplicationUser() { Id = Guid.NewGuid().ToString(),UserName = model.Email,Email = model.Email }; result = await UserManager.CreateAsync(user); if (!result.Succeeded) { return GetErrorResult(result); } var info = new ExternalLoginInfo() { DefaultUserName = model.Email,Login = new UserLoginInfo(model.Provider,externalLogin.ProviderKey) }; result = await UserManager.AddLoginAsync(user.Id,info.Login); if (!result.Succeeded) { return GetErrorResult(result); } identity = await UserManager.CreateIdentityAsync(user,OAuthDefaults.AuthenticationType); IEnumerable<Claim> claims = externalLogin.GetClaims(); identity.AddClaims(claims); Authentication.SignIn(identity); } AuthenticationTicket ticket = new AuthenticationTicket(identity,new AuthenticationProperties()); var currentUtc = new Microsoft.Owin.Infrastructure.SystemClock().UtcNow; ticket.Properties.IssuedUtc = currentUtc; ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromDays(365)); var accesstoken = Startup.OAuthOptions.AccesstokenFormat.Protect(ticket); Request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer",accesstoken); // Create the response building a JSON object that mimics exactly the one issued by the default /Token endpoint JObject token = new JObject( new JProperty("userName",user.UserName),new JProperty("id",user.Id),new JProperty("access_token",accesstoken),new JProperty("token_type","bearer"),new JProperty("expires_in",TimeSpan.FromDays(365).TotalSeconds.ToString()),new JProperty(".issued",currentUtc.ToString("ddd,dd MMM yyyy HH':'mm':'ss 'GMT'")),new JProperty(".expires",currentUtc.Add(TimeSpan.FromDays(365)).ToString("ddd,dd MMM yyyy HH:mm:ss 'GMT'")) ); return Ok(token); }
将此帮助方法添加到AccountController.cs中的助手区域中的ExternalLoginData类
public static async Task < ExternalLoginData > FromToken(string provider,string accesstoken) { string verifyTokenEndPoint = "",verifyAppEndpoint = ""; if (provider == "Facebook") { verifyTokenEndPoint = string.Format("https://graph.facebook.com/me?access_token={0}",accesstoken); verifyAppEndpoint = string.Format("https://graph.facebook.com/app?access_token={0}",accesstoken); } else if (provider == "Google") { // not implemented yet return null; //verifyTokenEndPoint = string.Format("https://www.googleapis.com/oauth2/v1/tokeninfo?access_token={0}",accesstoken); } else { return null; } HttpClient client = new HttpClient(); Uri uri = new Uri(verifyTokenEndPoint); HttpResponseMessage response = await client.GetAsync(uri); ClaimsIdentity identity = null; if (response.IsSuccessstatusCode) { string content = await response.Content.ReadAsstringAsync(); dynamic iObj = (Newtonsoft.Json.Linq.JObject) Newtonsoft.Json.JsonConvert.DeserializeObject(content); uri = new Uri(verifyAppEndpoint); response = await client.GetAsync(uri); content = await response.Content.ReadAsstringAsync(); dynamic appObj = (Newtonsoft.Json.Linq.JObject) Newtonsoft.Json.JsonConvert.DeserializeObject(content); identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType); if (provider == "Facebook") { if (appObj["id"] != Startup.facebookAuthOptions.AppId) { return null; } identity.AddClaim(new Claim(ClaimTypes.NameIdentifier,iObj["id"].ToString(),ClaimValueTypes.String,"Facebook","Facebook")); } else if (provider == "Google") { //not implemented yet } } if (identity == null) { return null; } Claim providerKeyClaim = identity.FindFirst(ClaimTypes.NameIdentifier); if (providerKeyClaim == null || String.IsNullOrEmpty(providerKeyClaim.Issuer) || String.IsNullOrEmpty(providerKeyClaim.Value)) { return null; } if (providerKeyClaim.Issuer == ClaimsIdentity.DefaultIssuer) { return null; } return new ExternalLoginData { LoginProvider = providerKeyClaim.Issuer,ProviderKey = providerKeyClaim.Value,UserName = identity.FindFirstValue(ClaimTypes.Name) }; } }
最后由该操作使用的RegisterExternalTokenBindingModel.
public class RegisterExternalTokenBindingModel { [required] [display(Name = "Email")] public string Email { get; set; } [required] [display(Name = "Token")] public string Token { get; set; } [required] [display(Name = "Provider")] public string Provider { get; set; } }
是的,我们在注册时传递电子邮件以及令牌细节,这不会导致您在使用Twitter时更改代码,因为Twitter不提供用户电子邮件.我们验证令牌来自我们的应用程序.一旦电子邮件注册,被黑客或别人的令牌不能用于更改电子邮件或获取该电子邮件的本地令牌,因为它将始终为实际的用户授予社交令牌的本地令牌,无论发送的电子邮件如何.
RegisterExternalToken端点用于以两种方式获取令牌,即注册用户并发送本地令牌,或者如果用户已注册,则发送令牌.
今天关于在Rest API中使用Facebook为Express和NodeJS中的JWT维护秘密密钥和访问令牌和rest for api的分享就到这里,希望大家有所收获,若想了解更多关于4.4 权限拦截控制\AccessToken jwt-博客后端Api-NodeJs+Express+Mysql实战、android – Facebook SDK 3.0 – 获取Facebook用户名和访问令牌、angularjs – 保存密钥和访问令牌在快速和NodeJS与Facebook的Rest API中的JWT、asp.net – MVC 5 Web API与Facebook访问令牌到RegisterExternal而不需要Cookie等相关知识,可以在本站进行查询。
本文标签: