EJS: res.locals не виден на каждой странице - PullRequest
0 голосов
/ 28 февраля 2019

Я действительно новичок в веб-разработке и пытаюсь создать небольшое приложение с Google oAuth, используя NodeJS express и EJS.Проблема в том, что я не очень хорошо понимаю, как промежуточные программы соединяются друг с другом и так далее, поэтому у меня есть то, что у меня есть:

app.js и auth.js, настроенные как в в этом уроке Google и заголовок EJS, который отображается на каждой странице моего приложения, он выглядит следующим образом:

<% if (locals.profile) { %>
        <span style="display:inline-block; width:150px;">
            <a href="#" class="badge badge-primary"> <%= profile.displayName %> </a>
        </span>

        <a class="btn btn-sm btn-outline-secondary" href= <%=logout%> >Log Out</a>    
<% } else { %>
        <a class="btn btn-sm btn-outline-secondary" href="/auth/login">Log In</a>
<% } %>

Итак, проблема в том, что когда я вхожу через /auth/login, скажем, /index, ячем вернуться к указанному \index, но заголовок остается пустым и предлагает мне войти в систему

Но если я добавлю router.get('/leaderboard', authRequired); в конец моего auth.js, заголовок будет работать, как и ожидалось (покажите мне мой логинНазовите и отобразите кнопку «Выйти» вместо «Войти»), но только на этом маршруте (например, /leaderboard)

Я пробовал router.get('/', authRequired);, и он работает нормально, но для входа требуется пользовательчтобы получить доступ к индексу, что нехорошо, я хочу, чтобы пользователи свободно перемещались по большинству страниц (учитывая, что это приложение типа блога: вы можете просматривать другие блоги, но не можете получить доступ к «edit-my-profile» или «new-»).сообщение, пока вы не вошли в систему)

Я также попытался установить locals и вызов extractProfile и addTemplateVariables вручную из get('/auth/login') и других мест (я признаюсь, слепо), но это не сработало вообще.

Я чувствую себя застрявшим и как будто я упускаю что-то важное в пониманииКак выразить себя работает.Кто-нибудь может указать мне, что это такое?

Любая помощь приветствуется!

PS 1: я тестирую на localhost

PS 2: вот мой auth.js:

  // Copyright 2017, Google, Inc.
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  //    http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.

  'use strict';

  const express = require('express');
  const config = require('./config');

  // [START setup]
  const passport = require('passport');
  const GoogleStrategy = require('passport-google-oauth20').Strategy;

  function extractProfile(profile) {
    let imageUrl = '';
    if (profile.photos && profile.photos.length) {
      imageUrl = profile.photos[0].value;
    }
    let email = '';
    if (profile.emails && profile.emails.length) {
      email = profile.emails[0].value;
    }

    return {
      id: profile.id,
      displayName: profile.displayName,
      image: imageUrl,
      email: email,
      name: profile.name,
    };
  }

  // Configure the Google strategy for use by Passport.js.
  //
  // OAuth 2-based strategies require a `verify` function which receives the
  // credential (`accessToken`) for accessing the Google API on the user's behalf,
  // along with the user's profile. The function must invoke `cb` with a user
  // object, which will be set at `req.user` in route handlers after
  // authentication.
  passport.use(
    new GoogleStrategy(
      {
        clientID: config.get('OAUTH2_CLIENT_ID'),
        clientSecret: config.get('OAUTH2_CLIENT_SECRET'),
        callbackURL: config.get('OAUTH2_CALLBACK'),
        accessType: 'offline',
        userProfileURL: 'https://www.googleapis.com/oauth2/v3/userinfo',
      },
      (accessToken, refreshToken, profile, cb) => {
        // Extract the minimal profile information we need from the profile object
        // provided by Google

        cb(null, extractProfile(profile));
      }
    )
  );

  passport.serializeUser((user, cb) => {
    cb(null, user);
  });
  passport.deserializeUser((obj, cb) => {
    cb(null, obj);
  });
  // [END setup]

  const router = express.Router();

  // [START middleware]
  // Middleware that requires the user to be logged in. If the user is not logged
  // in, it will redirect the user to authorize the application and then return
  // them to the original URL they requested.
  function authRequired(req, res, next) {
    if (!req.user) {
      req.session.oauth2return = req.originalUrl;
      return res.redirect('/auth/login');
    } else {
      res.locals.profile = req.user;

        res.locals.login = `/auth/login?return=${encodeURIComponent(
          req.originalUrl
        )}`;
        res.locals.logout = `/auth/logout?return=${encodeURIComponent(
          req.originalUrl
        )}`;
    }
    next();
  }

  // Middleware that exposes the user's profile as well as login/logout URLs to
  // any templates. These are available as `profile`, `login`, and `logout`.
  function addTemplateVariables(req, res, next) {
    res.locals.profile = req.user;

    res.locals.login = `/auth/login?return=${encodeURIComponent(
      req.originalUrl
    )}`;
    res.locals.logout = `/auth/logout?return=${encodeURIComponent(
      req.originalUrl
    )}`;
    next();
  }
  // [END middleware]

  // Begins the authorization flow. The user will be redirected to Google where
  // they can authorize the application to have access to their basic profile
  // information. Upon approval the user is redirected to `/auth/google/callback`.
  // If the `return` query parameter is specified when sending a user to this URL
  // then they will be redirected to that URL when the flow is finished.
  // [START authorize]
  router.get(
    // Login url
    '/auth/login',

    // Save the url of the user's current page so the app can redirect back to
    // it after authorization
    (req, res, next) => {
      if (req.query.return) {
        req.session.oauth2return = req.query.return;
      }
      next();
    },

    // Start OAuth 2 flow using Passport.js
    passport.authenticate('google', {scope: ['email', 'profile']})
  );
  // [END authorize]

  // [START callback]
  router.get(
    // OAuth 2 callback url. Use this url to configure your OAuth client in the
    // Google Developers console
    '/auth/google/callback',

    // Finish OAuth 2 flow using Passport.js
    passport.authenticate('google'),

    // Redirect back to the original page, if any
    (req, res) => {
      const redirect = req.session.oauth2return || '/';
      delete req.session.oauth2return;
      res.redirect(redirect);
    }
  );
  // [END callback]

  // Deletes the user's credentials and profile from the session.
  // This does not revoke any active tokens.
  router.get('/auth/logout', (req, res) => {
    req.logout();
    res.redirect('/');
  });

  router.get('/leaderboard', authRequired);

  module.exports = {
    extractProfile: extractProfile,
    router: router,
    required: authRequired,
    template: addTemplateVariables,
  };
...