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

时间:2020-09-08 15:19:09

标签: graphql apollo apollo-server

试图通过身份验证实现Apollo GraphQL服务器,并坚持正确地进行操作。

我想按here所述在数据模型中实现授权,所以我的config's context函数如下:

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 */ },
});

现在在配置对象中,我定义dataSources如下:

const config = {
    context,
    dataSources: () => ({
        UsersAPI: new UsersAPI({ UserModel })
    })

}

严格按照阿波罗手册进行。

主要问题是如何正确传递dataSources进行建模?还是如果我以上述方式使用模型,就可以完全放弃dataSources?每个模型都应该自己访问它吗?

更新在阅读了一些API之后,我发现DataSource也可以访问上下文。从体系结构的角度来看,将所有身份验证逻辑如下移至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;
    }
}

0 个答案:

没有答案