针对 Google 重定向 URI 不允许使用片段网址的解决方法



我用mac开发一个MEAN堆栈项目。我的网页https://localhost:3000/#/login并且https://localhost:3000/#/new工作(请注意,我的所有页面都需要在中间有/#/才能工作)。https://localhost:3000/#/new有一个按钮,可以通过passportjs.在我的routes ==> index.js我设定

var express = require('express');
var router = express.Router();
... ...
router.get('/auth/google', passport.authenticate('google', { scope: ['profile', 'email'] }));
router.get('/auth/google/callback',
passport.authenticate('google', { successRedirect: '/login',
failureRedirect: '/login' }));

Google APIs ==> Credentials,当我https://localhost:3000/auth/google/callback设置为Authorized redirect URIs时。单击我页面上的登录按钮返回错误

Error: redirect_uri_mismatch
The redirect URI in the request, https://localhost:3000/auth/facebook/callback, does not match the ones authorized for the OAuth client. Visit https://console.developers.google.com/apis/credentials/oauthclient/367100934152-7csfhcdnkapil4obku1pr2cnrsmthk61.apps.googleusercontent.com?project=367100934152 to update the authorized redirect URIs.

我想这是因为https://localhost:3000/auth/facebook/callback不是我的应用程序的有效 URI,但是如果我在设置页面中设置https://localhost:3000/#/auth/facebook/callback,则不允许:Invalid Redirect: https://localhost:3000/#/auth/google/callback cannot contain a fragment.

那么,有谁知道我是否可以修改我的应用程序以在没有#的情况下工作,以便https://localhost:3000/loginhttps://localhost:3000/new等都可以工作?因此,https://localhost:3000/auth/facebook/callback也将是一个有效的 URI...

编辑 1:

根据@Sevran的回答和文档如何配置服务器以使用 html5mode,我做了以下操作:

1) 在app.config中添加$locationProvider.html5Mode(true)

2)在index.ejs中添加了<base href="/" />(注意我在项目中没有index.html)

3)保持.state('new', url: '/new', ...app.config

4)在httpd-vhosts.conf什么也没做,它有<VirtualHost *:80><VirtualHost *:433>,因为我认为我的服务器是由express.js而不是httpd-vhosts.conf控制的,并且端口是3000的。

5)没有像这个答案那样在项目中添加.htaccess

6)在app.js中添加以下内容,我也尝试将index.html更改为index.ejs

app.use('/js', express.static(__dirname + '/js'));
app.use('/dist', express.static(__dirname + '/../dist'));
app.use('/css', express.static(__dirname + '/css'));
app.use('/partials', express.static(__dirname + '/partials'));
app.all('/*', function(req, res, next) {
// Just send the index.html for other files to support HTML5Mode
res.sendFile('index.html', { root: __dirname });
});

测试显示

  1. 在 URL 栏中输入https://localhost:3000/#/new将变为https://localhost:3000/new,并加载相应的页面。

  2. 在 URL 栏中输入https://localhost:3000/new会引发not found 404错误。

  3. 在 URL 栏中输入https://localhost:3000/auth/google会提高Error: redirect_uri_mismatch,如上所示。

总而言之,我认为重写(没有#的 url)应该通过 express 管理,但我发布的代码没有完成这项工作。关于.htaccess,我也试图将其放在httpd-vhosts.confDocumentRoot或项目的根文件夹中,但没有帮助。

在 app->init.js 在配置中启用以下模式

$locationProvider.html5Mode({
enabled: true,
requireBase: false
}).hashPrefix('!');

您可以使用 HTML5 模式从网址中删除哈希:

appModule.config(['$locationProvider', function($locationProvider) {
$locationProvider.html5Mode(true);
}]);

不要忘记在<head>标签中设置底座:

<head>
<base href="/">
...
</head>

请注意,如果您使用的是Angular 1.6,则还需要更改hashPrefix

appModule.config(['$locationProvider', function($locationProvider) {
$locationProvider.html5Mode(true);
$locationProvider.hashPrefix(''); // remove the ! from URL
}]);

有关更新日志的更多信息,请单击此处

您必须进行的更改:

1)角度边:正如您已经更改的那样

$locationProvider.html5Mode(true) in app.config
added <base href="/" /> in index.ejs
keeps .state('new', url: '/new', ... in app.config

2)HTA 访问

RewriteEngine   On
RewriteBase     /
RewriteCond     %{REQUEST_URI} !^(/index.php|/img|/js|/css|/robots.txt|/favicon.ico)
RewriteCond     %{REQUEST_FILENAME} !-f
RewriteCond     %{REQUEST_FILENAME} !-d
RewriteRule     ./index.html [L]

3)您需要从服务器端进行此更改,

如果使用 apache:

<VirtualHost *:80>
ServerName my-app
DocumentRoot /path/to/app
<Directory /path/to/app>
RewriteEngine on
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html to allow html5 state links
RewriteRule ^ index.html [L]
</Directory>
</VirtualHost>

在上面的my-app将是应用程序名称。 和DocumentRootDirectory路径应该是应用程序根目录的完整路径

对于快递:

var express = require('express');
var app = express();
app.use('/js', express.static(__dirname + '/js'));
app.use('/dist', express.static(__dirname + '/../dist'));
app.use('/css', express.static(__dirname + '/css'));
app.use('/partials', express.static(__dirname + '/partials'));
app.all('/*', function(req, res, next) {
// Just send the index.html for other files to support HTML5Mode
res.sendFile('index.html', { root: __dirname });
});
app.listen(3006); //the port you want to use

这是有关它的文档

最新更新