如何让 Foxx 服务使用基本集合进行身份验证操作?例如,我想要位于 https://docs.arangodb.com/3.11/develop/foxx-microservices/guides/authentication-and-sessions/ 的用户管理教程 使用集合“users”和“sessions”而不是“test_users”和“test_sessions”,其中“test”是我的安装点的名称。
我想运行多个服务,所有服务都在相同的基础集合上运行。但是,如果我按照教程中给出的内容进行操作,我最终会得到特定于服务的身份验证集合和路线,这对我来说没有多大意义。
我的setup.js是;
'use strict';
const db = require('@arangodb').db;
const sessions = module.context.collectionName('sessions');
const users = module.context.collectionName('users');
if (!db._collection(sessions)) {
db._createDocumentCollection(sessions);
}
if (!db._collection(users)) {
db._createDocumentCollection(users);
}
db._collection(users).ensureIndex({
type: 'hash',
fields: ['username'],
unique: true
});
我的index.js是;
'use strict';
const joi = require('joi');
const createAuth = require('@arangodb/foxx/auth');
const createRouter = require('@arangodb/foxx/router');
const sessionsMiddleware = require('@arangodb/foxx/sessions');
// const db = require('@arangodb').db;
const auth = createAuth();
const router = createRouter();
const users = db._collection('users');
const sessions = sessionsMiddleware({
storage: module.context.collection('sessions'),
transport: 'cookie'
});
module.context.use(sessions);
module.context.use(router);
// continued
router.post('/signup', function (req, res) {
const user = {};
try {
user.authData = auth.create(req.body.password);
user.username = req.body.username;
user.perms = [];
const meta = users.save(user);
Object.assign(user, meta);
} catch (e) {
// Failed to save the user
// We'll assume the uniqueness constraint has been violated
res.throw('bad request', 'Username already taken', e);
}
req.session.uid = user._key;
req.sessionStorage.save(req.session);
res.send({success: true});
})
.body(joi.object({
username: joi.string().required(),
password: joi.string().required()
}).required(), 'Credentials')
.description('Creates a new user and logs them in.');
我尝试使用
const users = db._collection('users');
而不是 const users = module.context.collection('users');
但这会引发 swagger api 错误。
要实现此目的,您需要在所有文件中将集合名称的分配从
module.context.collectionName('nameOfCollection')
更改为 'nameOfCollection'
,因为 module.context.collectionName
在字符串中添加服务名称前缀
所以
setup.js
const sessions = 'sessions';
const users = 'users';
index.js
const users = db._collection('users');
const sessions = sessionsMiddleware({
storage: 'sessions',
transport: 'cookie'
});
但是,当更多服务需要访问相同的底层集合时,这种方法是反模式的(例如,拆除一个服务可以删除其他服务的这些集合)。
对于这种情况,您应该使用依赖项,只有您的身份验证服务应该有权访问其自己的集合,其他服务应该将身份验证服务作为依赖项并通过身份验证服务访问身份验证数据。
认证服务需要有
在manifest.json中
"provides": {
"myauth": "1.0.0"
}
在index.js中或您在manifest.json中指向
main
的文件
module.exports = {
isAuthorized (id) {
return false; // your code for validating if user is authorized
}
};
消费服务需要有
在manifest.json中
"dependencies": {
"myauth": {
"name": "myauth",
"version": "^1.0.0",
"description": "Auth service.",
"required": true
}
}
然后就可以注册并调用了
const myauth = module.context.dependencies.myauth;
if (myauth.isAuthorized()) {
// your code
} else {
res.throw(401);
}
有关请求授权的进一步步骤,请检查如何使用 中间件 和 会话中间件
神速