EJS:并非在每个页面上都显示res.locals

时间:2019-02-28 11:29:54

标签: javascript node.js express oauth ejs

我真的是Web开发的新手,我正在尝试使用NodeJS Express和EJS与google oAuth制作一个小型应用程序。问题是我对中间件之间如何相互连接以及如何真正了解不多,所以我有:

this Google tutorial中进行配置的

app.js和auth.js以及呈现在我应用程序每个页面中的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,但标题仍然空白并为我提供登录信息

但是,如果我在我的auth.js末尾添加router.get('/leaderboard', authRequired);,则标题将按预期工作(请向我显示我的登录名并显示“注销”按钮,而不是“登录”),但仅在这条路线上(例如/leaderboard

我尝试了router.get('/', authRequired);,但工作正常,但是它要求用户登录才能访问索引,这不好,我希望用户自由浏览大部分页面(考虑到它是博客类型的应用程序:您可以查看其他博客,但在您未登录时无法访问“编辑我的个人资料”或“新帖子”页面)

我还尝试设置本地人,并从extractProfile和其他地方手动调用addTemplateVariablesget('/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,
  };

0 个答案:

没有答案