Я действительно новичок в веб-разработке и пытаюсь создать небольшое приложение с 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,
};