认证¶
$ npm install @feathersjs/authentication --save
@feathersjs/authentication 模块帮助使用JWT进行身份验证. 它有三个主要目的:
设置
/authentication端点以创建JSON Web令牌(JWT). JWT用作访问令牌. 您可以在 jwt.io 了解更多关于JWT的信息.为所有Feathers传输提供一致的身份验证API
为使用 Passport 策略保护端点的身份验证插件提供框架.
注解
If you are using a 0.x version of migration guide. The hooks that were once bundled with this module are now located at feathers-authentication-hooks.
互补插件¶
以下插件是互补的, 但完全是可选的:
在客户端上使用身份验证服务器: 验证客户端
本地(用户名/密码)身份验证: 本地验证
JWT身份验证: JWT身份验证
OAuth1身份验证: OAuth1 身份验证
OAuth2身份验证: OAuth2身份验证
app.configure(auth(options))¶
使用给定选项配置身份验证插件. 对于未提供的选项, 将使用 default options.
const auth = require('@feathersjs/authentication');
// Available options are listed in the "Default Options" section
app.configure(auth(options))
重要
在任何其他服务 之前, 必须配置插件.
选项¶
以下默认选项将与配置文件中的全局 auth 对象混合在一起.它会将混合选项设置回应用程序, 以便通过调用 app.get('authentication') 随时可用.它们都可以被覆盖, 并且是某些身份验证插件所必需的.
{
path: '/authentication', // the authentication service path
header: 'Authorization', // the header to use when using JWT auth
entity: 'user', // the entity that will be added to the request, socket, and context.params. (ie. req.user, socket.user, context.params.user)
secret: 'supersecret', // either the secret for HMAC algorithms or the PEM encoded private key for RSA and ECDSA.
service: 'users', // the service to look up the entity
passReqToCallback: true, // whether the request object should be passed to the strategies `verify` function
session: false, // whether to use sessions
cookie: {
enabled: false, // whether cookie creation is enabled
name: 'feathers-jwt', // the cookie name
httpOnly: false, // when enabled, prevents the client from reading the cookie.
secure: true // whether cookies should only be available over HTTPS
},
jwt: {
header: { typ: 'access' }, // by default is an access token but can be any type. This is not a typo!
audience: 'https://yourdomain.com', // The resource server where the token is processed
subject: 'anonymous', // Typically the entity id associated with the JWT
issuer: 'feathers', // The issuing server, application or resource
algorithm: 'HS256', // the algorithm to use
expiresIn: '1d' // the access token expiry
}
}
注解
The typ in the JWT header options is not a typo.
It is the typ parameter defined in the JWT specification.
app.service(‘authentication’)¶
这个插件的核心是一个创建JWT的服务. 这是一个普通的Feathers服务, 它只实现了 create` `和 ``remove 方法. /authentication 服务提供``/auth/local`` 和 /auth/token 端点所具有的所有功能. 要选择策略, 客户端必须在请求正文中传递 strategy 名称. 根据使用的插件, 这将有所不同. 有关详细信息, 请参阅本页顶部列出的插件的文档.
service.create(data)¶
几乎每个Feathers应用程序都会使用 create 方法. 它基于插件上配置的 jwt 选项创建了一个JWT. 此方法的API使用 context 对象.
如果您手动生成JWT, 例如, 想要使用 `payload <https://jwt.io>`_``{userId:“abc123 ”}``创建一个JWT. :
const data = {payload: {userId: "abc123"}};
service.create(data);
例如, 如果您手动生成JWT, 则需要使用`payload <https://jwt.io>`_`` {userId:“abc123 ”}``创建JWT.
service.remove(data)¶
较少使用 remove 方法.它的主要目的是为“注销”过程添加钩子.例如, 在需要高度安全控制的服务中, 开发人员可以在执行令牌黑名单的 remove 方法上注册挂钩.
service.hooks({ before })¶
可以修改这些属性以更改``/authentication``服务的行为:
context.data.payload {Object}- 确定JWT的有效载荷context.params.payload {Object}- 还确定了JWT的有效载荷. “context.data.payload”中的任何匹配属性都将被这些覆盖. 坚持后钩.context.params.authenticated {Boolean}- 成功验证后, 将被设置为``true``, 除非它在before hook中设置为``false``.如果在before hook中将其设置为“false”, 则会阻止websocket被标记为已验证.坚持后钩.
service.hooks({ after })¶
context.params[entity] {Object}- 成功验证后, 将在此处填充从数据库中查找的``entity``. (默认选项是``user``. )
app.passport¶
app.passport.createJWT(payload, options)¶
``app.passport.createJWT(payload, options) -> 承诺``由`authentication service <#appserviceauthentication>`_用于生成JSON Web令牌.
payload {Object}- 成为JWT有效载荷. 还将包含一个表示到期时间戳的``exp``属性.options {Object}- the options passed to jsonwebtoken sign()secret {String | Buffer}- 要么是HMAC算法的秘密, 要么是用于RSA和ECDSA的PEM编码私钥.jwt- 有关其他可用选项, 请参阅 jsonwebtoken package docs. authenticate方法使用defaultjwt ``选项<#default-options>`_.直接使用此包时, 必须手动传递它们.
返回的 promise 用JWT解析或失败并出错.
app.passport.verifyJWT(token, options)¶
使用``options``验证传入的JWT``token``的签名和有效负载.
token {JWT}- JWT待验证.``options {Object}``传递给`jsonwebtoken的选项验证()<https://www.npmjs.com/package/jsonwebtoken#jwtverifytoken-secretorpublickey-options-callback>`_
secret {String |缓冲区- - HMAC算法的秘密, 或RSA和ECDSA的PEM编码私钥.有关其他可用选项, 请参阅`jsonwebtoken <https://www.npmjs.com/package/jsonwebtoken#jwtsignpayload-secretorprivatekey-options-callback>`_ package docs.
返回的``promise``使用有效负载解析或失败并显示错误.
auth.hooks.authenticate(strategies)¶
``@feathersjs/authentication``只包含一个钩子. 这个捆绑的``authenticate``钩子用于在服务方法上注册一组认证策略.
注解
这应该通常用在你的``/authentication``服务上. 没有它, 您可以点击``authentication``服务并生成JWT``adminToken``而无需身份验证(即匿名身份验证).
app.service('authentication').hooks({
before: {
create: [
// You can chain multiple strategies
auth.hooks.authenticate(['jwt', 'local']),
],
remove: [
auth.hooks.authenticate('jwt')
]
}
});
认证事件¶
只要客户端成功验证或“注销”, 就会在``app``对象上发出``login``和``logout``事件. (使用JWT时, 注销不会使JWT无效.(有关详细信息, 请阅读JWT部分.)这些事件仅在服务器上发出.
app.on(‘login’, callback))¶
app.on(‘logout’, callback))¶
这两个事件使用具有相同签名的``callback``函数.
result{Object} - 来自``authentication``服务的最终``context.result``.除非你在后钩子中自定义``context.response``, 否则它只包含``accessToken``, 它是JWT.meta{Object} - information about the request. The ``meta`` data varies per transport / provider as follows.Using
@feathersjs/express/restprovider{String} - 永远是``“rest ”``req{Object} - Express请求对象.res{Object} - Express响应对象.
使用``feathers-socketio``和``feathers-primus``:
provider{String} - 传输名称:socketio``或``primusconnection{Object} - 与钩子上下文中的``params``相同socket{SocketObject} - 当前用户的WebSocket对象. 它还包含``feathers``属性, 它与钩子上下文中的``params``相同.
快递中间件¶
有一个``authenticate``中间件. 它的使用方法与普通的Passport express中间件完全相同:
const cookieParser = require('cookie-parser');
app.post('/protected-route', cookieParser(), auth.express.authenticate('jwt'));
app.post('/protected-route-that-redirects', cookieParser(), auth.express.authenticate('jwt', {
failureRedirect: '/login'
}));
有关详细信息, 请参阅:doc:../../guides/auth/recipe.express-middleware.
包含并公开了其他中间件, 但您通常不需要担心它们:
emitEvents- 发出``login``和``logout``事件exposeCookies- 向Feathers公开cookie, 以便它们可用于钩子和服务. **默认情况下不使用它, 因为它的使用会将您的API暴露给CSRF漏洞.**只有在您真正知道自己在做什么的情况下才使用它.exposeHeaders- 向Feathers公开标题, 以便它们可用于钩子和服务. **默认情况下不使用它, 因为它的使用会将您的API暴露给CSRF漏洞.**只有在您真正知道自己在做什么的情况下才使用它.failureRedirect- 支持重定向auth失败. 仅在设置了``hook.redirect``时触发.successRedirect- 支持重定向auth成功. 仅在设置了``hook.redirect``时触发.setCookie- 支持在cookie中设置JWT访问令牌. 仅在启用cookie时启用.
注解
Feathers不会从cookie中读取访问令牌. 这会使API暴露于CSRF攻击. **这个 setCookie 功能主要用于帮助进行服务器端渲染.
完整的例子¶
这是一个使用 @feathersjs/authentication 进行本地身份验证的Feathers服务器的示例.
const feathers = require('@feathersjs/feathers');
const express = require('@feathersjs/express');
const socketio = require('@feathersjs/socketio');
const auth = require('@feathersjs/authentication');
const local = require('@feathersjs/authentication-local');
const jwt = require('@feathersjs/authentication-jwt');
const memory = require('feathers-memory');
const app = express(feathers());
app.configure(express.rest())
.configure(socketio())
.use(express.json())
.use(express.urlencoded({ extended: true }))
.configure(auth({ secret: 'supersecret' }))
.configure(local())
.configure(jwt())
.use('/users', memory())
.use('/', express.static(__dirname + '/public'))
.use(express.errorHandler());
app.service('users').hooks({
// Make sure `password` never gets sent to the client
after: local.hooks.protect('password')
});
app.service('authentication').hooks({
before: {
create: [
// You can chain multiple strategies
auth.hooks.authenticate(['jwt', 'local'])
],
remove: [
auth.hooks.authenticate('jwt')
]
}
});
// Add a hook to the user service that automatically replaces
// the password with a hash of the password, before saving it.
app.service('users').hooks({
before: {
find: [
auth.hooks.authenticate('jwt')
],
create: [
local.hooks.hashPassword({ passwordField: 'password' })
]
}
});
const port = 3030;
let server = app.listen(port);
server.on('listening', function() {
console.log(`Feathers application started on localhost:${port}`);
});

