如何以正确的方式使用apollo graphql服务器体系结构进行身份验证?

如何以正确的方式使用apollo graphql服务器体系结构进行身份验证?,graphql,apollo,apollo-server,Graphql,Apollo,Apollo Server,试图用身份验证实现Apollo GraphQL服务器,但遇到了如何正确实现的问题 我希望在数据模型中实现如上所述的授权,因此我的上下文函数如下所示: context: ({ req }) => { // get the user token from the headers const token = req.headers.authentication || ''; // try to retrieve a user with the token const user =

试图用身份验证实现Apollo GraphQL服务器,但遇到了如何正确实现的问题

我希望在数据模型中实现如上所述的授权,因此我的
上下文
函数如下所示:

context: ({ req }) => {
 // get the user token from the headers
 const token = req.headers.authentication || '';
  
 // try to retrieve a user with the token
 const user = getUser(token);

 // optionally block the user
 // we could also check user roles/permissions here
 if (!user) throw new AuthenticationError('you must be logged in to query this schema');  

 // add the user to the context
 return {
   user,
   models: {
     User: generateUserModel({ user }),
     ...
   }
 };
},
export const generateUserModel = ({ user }) => ({
 getAll: () => { /* fetching/transform logic for all users */ },
 getById: (id) => { /* fetching/transform logic for a single user */ },
 getByGroupId: (id) => { /* fetching/transform logic for a group of users */ },
});
const config = {
    context,
    dataSources: () => ({
        UsersAPI: new UsersAPI({ UserModel })
    })

}
我的用户模型如下:

context: ({ req }) => {
 // get the user token from the headers
 const token = req.headers.authentication || '';
  
 // try to retrieve a user with the token
 const user = getUser(token);

 // optionally block the user
 // we could also check user roles/permissions here
 if (!user) throw new AuthenticationError('you must be logged in to query this schema');  

 // add the user to the context
 return {
   user,
   models: {
     User: generateUserModel({ user }),
     ...
   }
 };
},
export const generateUserModel = ({ user }) => ({
 getAll: () => { /* fetching/transform logic for all users */ },
 getById: (id) => { /* fetching/transform logic for a single user */ },
 getByGroupId: (id) => { /* fetching/transform logic for a group of users */ },
});
const config = {
    context,
    dataSources: () => ({
        UsersAPI: new UsersAPI({ UserModel })
    })

}
现在在config object中,我定义了
数据源
,如下所示:

context: ({ req }) => {
 // get the user token from the headers
 const token = req.headers.authentication || '';
  
 // try to retrieve a user with the token
 const user = getUser(token);

 // optionally block the user
 // we could also check user roles/permissions here
 if (!user) throw new AuthenticationError('you must be logged in to query this schema');  

 // add the user to the context
 return {
   user,
   models: {
     User: generateUserModel({ user }),
     ...
   }
 };
},
export const generateUserModel = ({ user }) => ({
 getAll: () => { /* fetching/transform logic for all users */ },
 getById: (id) => { /* fetching/transform logic for a single user */ },
 getByGroupId: (id) => { /* fetching/transform logic for a group of users */ },
});
const config = {
    context,
    dataSources: () => ({
        UsersAPI: new UsersAPI({ UserModel })
    })

}
一切都严格遵守阿波罗手册

主要问题是如何正确地将
数据源
传递给模型?
或者如果我以上述方式使用模型,我可以完全放弃
数据源
?每个模型都应该自己访问它

更新在阅读了一些API之后,我发现
数据源
也可以访问上下文。从架构的角度来看,将所有身份验证逻辑移动到
DataSource
类是否是正确的决定,如下所示

export class UsersAPI extends DataSource {
    private UserModel: any;
    private context: any;
    private LoggedInUser: User;

    constructor({ UserModel }) {
        super();
        this.UserModel = UserModel;
    }

    /**
     * This is a function that gets called by ApolloServer when being setup.
     * This function gets called with the datasource config including things
     * like caches and context. We'll assign this.context to the request context
     * here, so we can know about the user making requests
     */
    initialize(config) {
        console.log('user object');
        this.loggedInUser = config.context.user;
        this.context = config.context;
    }

    
    async getUsers(): Promise<any> {
        if (!this.loggedInUsers) {
            throw new AuthenticationError('Must be Logged In');
        }
        const query = {};
        const users = await this.UserModel.find(query).lean();
        return users;
    }
}
导出类UsersAPI扩展数据源{
私有用户模型:任意;
私人背景:任何;
私有LoggedInUser:用户;
构造函数({UserModel}){
超级();
this.UserModel=UserModel;
}
/**
*这是一个在安装时由ApolloServer调用的函数。
*使用数据源配置调用此函数,包括
*比如缓存和上下文。我们将把this.context分配给请求上下文
*在这里,我们可以了解用户发出请求的情况
*/
初始化(配置){
log(“用户对象”);
this.loggedInUser=config.context.user;
this.context=config.context;
}
异步getUsers():承诺{
如果(!this.loggedInUsers){
抛出新的AuthenticationError('必须登录');
}
常量查询={};
const users=wait this.UserModel.find(query.lean();
返回用户;
}
}