laardee / serverless-authentication-boilerplate

Generic authentication boilerplate for Serverless framework
http://laardee.github.io/serverless-authentication-gh-pages
MIT License
569 stars 72 forks source link

Error: invalid_client The OAuth client was not found. #41

Open quantuminformation opened 7 years ago

quantuminformation commented 7 years ago

I've followed the setup instructions for this and the gh-pages example and am running it locally.

image

However when I press the google sign-in the browser visits the signin URL:

https://uz4g3f3m8i.execute-api.us-east-1.amazonaws.com/dev/authentication/signin/google

but I just get this:

image

laardee commented 7 years ago

@QuantumInformation hi, have you setup the OAuth client in google developer console and copied the id and secret to authentication/env.yml?

quantuminformation commented 7 years ago

@laardee I'm creating an app in the console now to try..

quantuminformation commented 7 years ago

So I added it:

image

but after auth with google

image

I get:

image

image

laardee commented 7 years ago

@QuantumInformation, I'm trying to reproduce the issue but without luck. Did you change anything in the signin handler code or serverless.yml? It seems that for some reason it breaks on signin handler.

quantuminformation commented 7 years ago

Heres my sign in file:

'use strict';

// Config
const slsAuth = require('serverless-authentication');

const config = slsAuth.config;
const utils = slsAuth.utils;

// Providers
const facebook = require('serverless-authentication-facebook');
const google = require('serverless-authentication-google');
const microsoft = require('serverless-authentication-microsoft');
const customGoogle = require('../custom-google');

// Common
const cache = require('../storage/cacheStorage');

const redirectProxyCallback = require('../helpers').redirectProxyCallback;

/**
 * Sign In Handler
 * @param proxyEvent
 * @param context
 */
function signinHandler(proxyEvent, context) {
  const event = {
    provider: proxyEvent.pathParameters.provider,
    stage: proxyEvent.requestContext.stage,
    host: proxyEvent.headers.Host
  };

  const providerConfig = config(event);

  cache.createState()
    .then((state) => {
      switch (event.provider) {
        case 'facebook':
          facebook.signinHandler(providerConfig, { scope: 'email', state },
            (err, data) => redirectProxyCallback(context, data));
          break;
        case 'google':
          google.signinHandler(providerConfig, { scope: 'profile email', state },
            (err, data) => redirectProxyCallback(context, data));
          break;
        case 'microsoft':
          microsoft.signinHandler(providerConfig, { scope: 'wl.basic wl.emails', state },
            (err, data) => redirectProxyCallback(context, data));
          break;
        case 'custom-google':
          // See ./customGoogle.js
          customGoogle.signinHandler(providerConfig, { state },
            (err, data) => redirectProxyCallback(context, data));
          break;
        default:
          utils.errorResponse({
            error: `Invalid provider: ${event.provider}` },
            providerConfig,
            (err, data) => redirectProxyCallback(context, data)
          );
      }
    })
    .catch(error =>
      utils.errorResponse(
        { error },
        providerConfig,
        (err, data) => redirectProxyCallback(context, data)
      ));
}

exports = module.exports = signinHandler;
frameworkVersion: ">=1.2.0 <2.0.0"

service: serverless-authentication # change this

provider:
  name: aws
  environment: ${file(./env.yml):${opt:stage, self:provider.stage}}
  iamRoleStatements:
    - Effect: Allow
      Action:
      - dynamodb:Scan
      - dynamodb:Query
      - dynamodb:PutItem
      - dynamodb:DeleteItem
      Resource: arn:aws:dynamodb:${self:provider.region}:*:*
    - Effect: Allow
      Action:
      - cognito-sync:*
      - cognito-identity:*
      Resource: arn:aws:cognito-identity:*:*:*
    - Effect: Allow
      Action:
      - cognito-idp:*
      Resource: arn:aws:cognito-idp:*:*:*
  runtime: nodejs4.3

package:
  exclude:
    - .git/**

# Functions

functions:
  signin:
    handler: handler.signin
    memorySize: 256
    timeout: 15
    events:
      - http:
          path: authentication/signin/{provider}
          method: get
          integration: lambda-proxy
  callback:
    handler: handler.callback
    memorySize: 256
    timeout: 15
    events:
      - http:
          path: authentication/callback/{provider}
          method: get
          integration: lambda-proxy
  refresh:
    handler: handler.refresh
    memorySize: 256
    timeout: 15
    events:
      - http:
          path: authentication/refresh/{refresh_token}
          method: get
          cors: true
          integration: lambda
          request:
            template:
              application/json: |
                {
                  "refresh_token":"$input.params('refresh_token')",
                  "id":"$input.params('id')",
                  "state":"$input.params('state')",
                  "host":"$input.params().header.get('host')",
                  "stage":"$context.stage"
                }
  authorize:
    handler: handler.authorize
  schema:
    handler: handler.schema

plugins:
  - deployment-info

resources:
  Description: ${self:provider.environment.SERVICE} [${self:provider.environment.STAGE}] template
  Resources:
    CacheTable:
      Type: AWS::DynamoDB::Table
      Properties:
        AttributeDefinitions:
        - AttributeName: token
          AttributeType: S
        - AttributeName: type
          AttributeType: S
        KeySchema:
        - AttributeName: token
          KeyType: HASH
        - AttributeName: type
          KeyType: RANGE
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1
        TableName: ${self:provider.environment.CACHE_DB_NAME}
#    UsersTable:
#      Type: AWS::DynamoDB::Table
#      Properties:
#        AttributeDefinitions:
#        - AttributeName: userId
#          AttributeType: S
#        KeySchema:
#        - AttributeName: userId
#          KeyType: HASH
#        ProvisionedThroughput:
#          ReadCapacityUnits: 1
#          WriteCapacityUnits: 1
#        TableName: ${self:provider.environment.USERS_DB_NAME}
quantuminformation commented 7 years ago

I'm going to try debug locally with https://github.com/dherault/serverless-offline#debug-process

laardee commented 7 years ago

Ok, it seems that the test are also broken. I'll try to fix those tonight.

laardee commented 7 years ago

@QuantumInformation, tests are fixed now. You could try if those helps you to trace the problem. Here are all the changes https://github.com/laardee/serverless-authentication-boilerplate/pull/43/files but, you only need to copy

then you can delete specs folder and specs-docker.sh.

Do you have Docker installed? Tests use Dockerized version of DynamoDB.

quantuminformation commented 7 years ago

So I don't get the error now, but I'm not getting the authenticate state now in the client after I click google sign-in

image

I've not used Docker locally, I'll try it soon to test.

quantuminformation commented 7 years ago

wow this is pretty slick

https://store.docker.com/editions/community/docker-ce-desktop-mac/plans/docker-ce-desktop-mac-tier?tab=instructions

quantuminformation commented 7 years ago

What store dynamodb did you use?

https://store.docker.com/

laardee commented 7 years ago

The docker-compose.yml uses https://hub.docker.com/r/dwmkerr/dynamodb/ image. I found that from some tutorial, there could be more popular images available also. Did all the tests pass? If so, something might be wrong in the deployment. Have you tried to remove the stack and deploy it again?