DEV Community

Kamruzzaman
Kamruzzaman

Posted on

An authentication process with AWS Cognito and node, express Graphql

To create an authentication process using AWS Cognito with a Node.js, Express, and GraphQL setup, you can follow these steps:

1. Set Up AWS Cognito User Pool
Create a User Pool:

  • 1. Go to the AWS Cognito dashboard and create a new User Pool.
  • 2. Configure sign-up and sign-in options (email, phone number, etc.).
  • 3. Set up security policies (password strength, MFA, etc.).
  • 4. Add app clients (for example, web or mobile applications).
  • 5. Save the pool ID and app client ID.

2. Install Necessary Packages
npm install express express-graphql graphql aws-sdk amazon-cognito-identity-js jsonwebtoken

3. Set Up Express Server
Create a basic Express server with GraphQL integration.

const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');

const app = express();

// GraphQL schema
const schema = buildSchema(`
  type Query {
    hello: String
  }

  type Mutation {
    signUp(email: String!, password: String!): String
    signIn(email: String!, password: String!): String
  }
`);

// Root resolver
const root = {
  hello: () => 'Hello world!',
  signUp: async ({ email, password }) => {
    // Sign up logic here
  },
  signIn: async ({ email, password }) => {
    // Sign in logic here
  },
};

app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true,
}));

app.listen(4000, () => console.log('Server running on http://localhost:4000/graphql'));

Enter fullscreen mode Exit fullscreen mode

4. Integrate AWS Cognito for Authentication
Set up the AWS Cognito logic for sign-up and sign-in.

const AWS = require('aws-sdk');
const AmazonCognitoIdentity = require('amazon-cognito-identity-js');
const jwt = require('jsonwebtoken');

const poolData = {
  UserPoolId: 'your-user-pool-id', // e.g., us-east-1_ExaMPle
  ClientId: 'your-client-id', // e.g., 1h57kf5cpq17m0emlq5hd17dil
};
const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);

const signUp = async ({ email, password }) => {
  return new Promise((resolve, reject) => {
    const attributeList = [
      new AmazonCognitoIdentity.CognitoUserAttribute({
        Name: 'email',
        Value: email,
      }),
    ];

    userPool.signUp(email, password, attributeList, null, (err, result) => {
      if (err) {
        reject(err);
        return;
      }
      resolve(`User ${result.user.getUsername()} signed up successfully`);
    });
  });
};

const signIn = async ({ email, password }) => {
  return new Promise((resolve, reject) => {
    const authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails({
      Username: email,
      Password: password,
    });

    const userData = {
      Username: email,
      Pool: userPool,
    };

    const cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
    cognitoUser.authenticateUser(authenticationDetails, {
      onSuccess: (result) => {
        const accessToken = result.getAccessToken().getJwtToken();
        resolve(accessToken);
      },
      onFailure: (err) => {
        reject(err);
      },
    });
  });
};

// Modify root resolver to use the signUp and signIn functions
const root = {
  hello: () => 'Hello world!',
  signUp: async ({ email, password }) => {
    try {
      return await signUp({ email, password });
    } catch (error) {
      throw new Error(error.message);
    }
  },
  signIn: async ({ email, password }) => {
    try {
      return await signIn({ email, password });
    } catch (error) {
      throw new Error(error.message);
    }
  },
};

Enter fullscreen mode Exit fullscreen mode

5. Testing the Authentication Process

  • Sign Up: mutation { signUp(email: "user@example.com", password: "StrongPassword123") }
  • Sign In: mutation { signIn(email: "user@example.com", password: "StrongPassword123") }

6. Secure GraphQL Endpoints
Use JWT tokens obtained from Cognito to secure your GraphQL endpoints.

const authenticate = (req, res, next) => {
  const token = req.headers.authorization;
  if (!token) {
    return res.status(401).send('Unauthorized');
  }

  jwt.verify(token, 'your-aws-cognito-jwt-verification-key', (err, decoded) => {
    if (err) {
      return res.status(401).send('Unauthorized');
    }
    req.user = decoded;
    next();
  });
};

app.use('/graphql', authenticate, graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true,
}));

Enter fullscreen mode Exit fullscreen mode

7. Handling Token Expiry and Refresh
Implement token refresh logic to handle token expiry using Cognito's refresh token.

This setup provides a basic framework for handling authentication using AWS Cognito in a Node.js, Express, and GraphQL environment. You can expand on this by adding more complex features such as MFA, user attributes, and more.

Top comments (0)