Постоянное состояние входа в систему с React & Auth0 (с использованием собственного NodeJS бэкэнда + паспорта JS) - PullRequest
0 голосов
/ 16 января 2020

Начинающий здесь. Я считаю, что проблема очень проста, но требует некоторого объяснения. Поэтому, пожалуйста, потерпите меня (или посмотрите ниже Сводка / Проблема ):

Я пытаюсь настроить auth0 с passport и gatsby. До сих пор я следовал этому руководству . Хотя я новичок, и я все еще очень борюсь. Если пользователь заходит на /account или что-либо за учетной записью /account/*, он / она будет перенаправлен на страницу входа / регистрации, предоставленную auth0. Сейчас все это обрабатывается серверной частью auth0 (пока).

Однако, Я бы хотел отойти от этого и использовать свой собственный node.js сервер . Я бы хотел интегрировать кнопки самостоятельно, например LOGIN или LOGIN WITH FACEBOOK, которые напрямую переводят пользователя в соответствующий механизм входа в систему.

Вот что у меня так далеко. Это nodejs сервер

const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const session = require('express-session');
const passport = require('passport');
const Auth0Strategy = require('passport-auth0');
const cors = require('cors');

passport.use(
  new Auth0Strategy(
    {
      domain: 'XXXX.auth0.com',
      clientID: 'XXXX',
      clientSecret:
        'XXXX',
      callbackURL: 'http://localhost:9000/callback',
      audience: 'https://XXXXXX.auth0.com/userinfo',
      responseType: 'code',
      scope: 'openid email profile'
    },
    function(accessToken, refreshToken, extraParam, profile, done) {
      return done(null, profile);
    }
  )
);

passport.serializeUser(function(user, done) {
  console.log('serialise');
  console.log(user);
  done(null, user);
});

passport.deserializeUser(function(user, done) {
  console.log('deserialise');
  // console.log(user)
  done(null, user);
});

const app = express();

// app.use(cors())

app.use(cors({ origin: 'http://localhost:8888' }));
// app.use(cors())

app.use(function(req, res, next) {
  // Website you wish to allow to connect
  res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8888');

  // Request methods you wish to allow
  res.setHeader(
    'Access-Control-Allow-Methods',
    'GET, POST, OPTIONS, PUT, PATCH, DELETE'
  );

  // Request headers you wish to allow
  res.setHeader(
    'Access-Control-Allow-Headers',
    'X-Requested-With,content-type'
  );

  // Set to true if you need the website to include cookies in the requests sent
  // to the API (e.g. in case you use sessions)
  res.setHeader('Access-Control-Allow-Credentials', true);

  // Pass to next layer of middleware
  next();
});

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.use(
  session({ secret: 'XXXXX', resave: true, saveUninitialized: true })
);

app.use(passport.initialize());
app.use(passport.session());

app.use(function(req, res, next) {
  res.locals.loggeedIn = false;
  if (req.session.passport && typeof req.session.passport.user !== undefined) {
    res.locals.loggedIn = true;
  }
  next();
});

app.get('/', function(req, res, next) {
  res.send('Hello from server');
});

app.get(
  '/login',
  passport.authenticate(
    'auth0',
    {
      domain: 'XXXXX.auth0.com',
      clientID: 'XXXXX',
      redirectUri: 'http://localhost:9000/callback',
      audience: 'https://XXXXX.auth0.com/userinfo',
      responseType: 'code',
      scope: 'openid email profile'
    },
    function(req, res, next) {
       res.redirect("http://localhost:8888/welcome")
    }
  )
);

app.get('/logout', function(req, res, next) {
  req.logout();
  res.redirect('http://localhost:8888/bye');
});

app.get(
  '/login/google',
  passport.authenticate('auth0', { connection: 'google-oauth2' }),
  function(req, res) {
    console.log(req);
    res.redirect('/');
  }
);

app.get(
  '/login/facebook',
  passport.authenticate('auth0', { connection: 'facebook' }),
  function(req, res) {
    res.redirect('/');
  }
);

app.get(
  '/callback',
  passport.authenticate('auth0', {
    failureRedirect: '/failure'
  }),
  function(req, res) {
    res.redirect('http://localhost:8888/callback');
    // res.redirect('/user');
  }
);

app.get('/user', function(req, res, next) {
  res.send(req.user);
});

app.get('/failure', function(req, res, next) {
  res.send('Failure');
});

app.listen(9000, function() {
  console.log('running');
});

Теперь сервер, кажется, работает. он регистрирует пользователя, дает мне пользователя, когда я go на /user и перенаправляет на localhost:8888/callback.

Однако, на localhost:8888/callback все останавливается. Когда он прибывает туда, он должен перенаправить, но это никогда не происходит. Это застряло здесь.

Вот код для localhost: 8888 / callback :

import React from 'react';
import { handleAuthentication } from '../utils/auth';

const Callback = () => {
  handleAuthentication();

  return <p>Loading...</p>;
};

export default Callback;

и handleAuthentication здесь:

const setSession = (cb = () => {}) => (err, authResult) => {

  if (err) {
    navigate('/');
    cb();
    return;
  }

  console.log(authResult); 
    // this is null when using my own nodejs server, when going through the
    // standard auth0 version, there is an object here and everything is 
    // working fine!

  if (authResult && authResult.accessToken && authResult.idToken) {
    let expiresAt = authResult.expiresIn * 1000 + new Date().getTime();
    tokens.accessToken = authResult.accessToken;
    tokens.idToken = authResult.idToken;
    tokens.expiresAt = expiresAt;
    user = authResult.idTokenPayload;
    localStorage.setItem('isLoggedIn', true);
    navigate('/account');
    cb();
  }
};


export const handleAuthentication = () => {
  if (!isBrowser) {
    return;
  }

  console.log('HANDLING AUTH');
  auth.parseHash(setSession());
};

Для справки, вот полная аутентификация. js файл

import auth0 from 'auth0-js';
import { navigate } from 'gatsby';

const isBrowser = typeof window !== 'undefined';

const auth = isBrowser
  ? new auth0.WebAuth({
      domain: process.env.AUTH0_DOMAIN,
      clientID: process.env.AUTH0_CLIENTID,
      redirectUri: process.env.AUTH0_CALLBACK,
      responseType: 'token id_token',
      scope: 'openid profile email'
    })
  : {};

const tokens = {
  accessToken: false,
  idToken: false,
  expiresAt: false
};

let user = {};

export const isAuthenticated = () => {
  if (!isBrowser) {
    return;
  }

  return localStorage.getItem('isLoggedIn') === 'true';
};

export const login = () => {
  if (!isBrowser) {
    return;
  }

  auth.authorize();
};

const setSession = (cb = () => {}) => (err, authResult) => {

  if (err) {
    navigate('/');
    cb();
    return;
  }

  console.log(authResult); //this is null !!!

  if (authResult && authResult.accessToken && authResult.idToken) {
    let expiresAt = authResult.expiresIn * 1000 + new Date().getTime();
    tokens.accessToken = authResult.accessToken;
    tokens.idToken = authResult.idToken;
    tokens.expiresAt = expiresAt;
    user = authResult.idTokenPayload;
    localStorage.setItem('isLoggedIn', true);
    navigate('/account');
    cb();
  }
};

export const silentAuth = callback => {
  if (!isAuthenticated()) return callback();
  auth.checkSession({}, setSession(callback));
};

export const handleAuthentication = () => {
  if (!isBrowser) {
    return;
  }

  console.log('HANDLING AUTH');
  auth.parseHash(setSession());
};

export const getProfile = () => {
  return user;
};

export const logout = () => {
  localStorage.setItem('isLoggedIn', false);
  auth.logout();
};

Сводка / вопрос Кажется, проблема в том, что authResult всегда null при входе с моего собственного nodejs сервера - и тогда он не go входит в блок if и сохраняет сеанс. Я не понимаю, что именно мне нужно изменить здесь, чтобы оно сохраняло состояние, аналогично тому, как оно работает сейчас на сервере auth0s?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...