重定向到 github omniauth 路由时如何解决 CORS 错误?
How to solve CORS error when redirecting to github omniauth route?
我正在尝试构建一个简单的应用程序,目前仅使用 GitHub 登录名进行身份验证。我在后端使用 Rails v5.2.3,在前端使用 React。目前,我的根组件中有一个按钮可以向我的后端发送 ajax 请求。该请求将在我的 SessionsController
中执行一个操作,该操作将重定向到 /auth/github
路由并开始 GitHub 身份验证周期。
我认为这是我遇到错误的步骤。
我的浏览器控制台给我这个错误信息:
Access to XMLHttpRequest at 'https://github.com/login/oauth/authorize?
client_id=db494fb7eadbc0c6129d&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Fgithub%2Fcallback&resp
onse_type=code&state=79557eda02a2340f9c02b5254f053528314ea750704690ae' (redirected from
'http://localhost:3000/authenticate/github') from origin 'http://localhost:3000' has been blocked by CORS
policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
以下是一些我认为相关的文件:
Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '2.5.1'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.2.3'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
# Use Puma as the app server
gem 'puma', '~> 3.11'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'mini_racer', platforms: :ruby
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.2'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
gem 'omniauth-github', github: 'omniauth/omniauth-github', branch: 'master'
gem 'figaro'
gem 'rack-cors'
# Use ActiveStorage variant
# gem 'mini_magick', '~> 4.8'
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.1.0', require: false
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end
group :development do
# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
gem 'web-console', '>= 3.3.0'
gem 'listen', '>= 3.0.5', '< 3.2'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
gem 'better_errors'
gem 'binding_of_caller'
gem 'pry-rails'
end
group :test do
# Adds support for Capybara system testing and selenium driver
gem 'capybara', '>= 2.15'
gem 'selenium-webdriver'
# Easy installation and use of chromedriver to run system tests with Chrome
gem 'chromedriver-helper'
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
routes.rb
Rails.application.routes.draw do
get '/authenticate/:type', to: 'sessions#authenticate'
get '/auth/:provider/callback', to: 'sessions#create'
root to: 'static_pages#root'
end
initializers/github.rb
Rails.application.config.middleware.use OmniAuth::Builder do
provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET']
end
sessions_controller.rb
class SessionsController < ApplicationController
def authenticate
redirect_to '/auth/github' if params[:type] == 'github'
end
def create
@user = User.find_or_create_from_oauth(auth_params)
if @user
render json: @user
else
render json: [params['error']], status: 422
end
end
private
def auth_params
request.env['omniauth.auth']
end
end
root.jsx
import React, { useState } from 'react';
import axios from 'axios';
const Root = () => {
const [name, setName] = useState('no name yet');
const githubLogin = () => {
axios.get('authenticate/github')
.then(user => setName(user.name));
}
return (
<div>
<button onClick={githubLogin}>Github Login</button>
<h1>Name: {name}</h1>
</div>
)
}
export default Root;
经过一些研究,我看到了一些添加 rack-cors
gem 的建议。我尝试这样做并添加了这个初始化程序。
initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
puts 'setting up cors'
allow do
origins '*'
resource '*', headers: :any, methods: [:get, :post, :patch, :put]
end
end
在设置 oauth 方面,我还是个新手,我正在努力弄清楚,但这让我很困惑。我不确定我的重定向是否得到 Headers 它不需要被阻止,我确定从这里去哪里。
如有任何帮助,我们将不胜感激。如果我可以提供任何其他信息,请告诉我。谢谢。
您收到错误是因为重定向发生在 XHR 的上下文中。
一个解决方案是为您的控制器创建 XHR,它会 return 一个 URL 客户端必须遵循。
另一种方法是不制作 XHR 并在您的操作中使用普通的 link。
无论哪种方式,您都应该确保您不向 JS 请求 GitHub URL。它必须是普通的 HTTP(s) 请求。
我正在尝试构建一个简单的应用程序,目前仅使用 GitHub 登录名进行身份验证。我在后端使用 Rails v5.2.3,在前端使用 React。目前,我的根组件中有一个按钮可以向我的后端发送 ajax 请求。该请求将在我的 SessionsController
中执行一个操作,该操作将重定向到 /auth/github
路由并开始 GitHub 身份验证周期。
我认为这是我遇到错误的步骤。
我的浏览器控制台给我这个错误信息:
Access to XMLHttpRequest at 'https://github.com/login/oauth/authorize?
client_id=db494fb7eadbc0c6129d&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Fgithub%2Fcallback&resp
onse_type=code&state=79557eda02a2340f9c02b5254f053528314ea750704690ae' (redirected from
'http://localhost:3000/authenticate/github') from origin 'http://localhost:3000' has been blocked by CORS
policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
以下是一些我认为相关的文件:
Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '2.5.1'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.2.3'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
# Use Puma as the app server
gem 'puma', '~> 3.11'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'mini_racer', platforms: :ruby
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.2'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
gem 'omniauth-github', github: 'omniauth/omniauth-github', branch: 'master'
gem 'figaro'
gem 'rack-cors'
# Use ActiveStorage variant
# gem 'mini_magick', '~> 4.8'
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.1.0', require: false
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end
group :development do
# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
gem 'web-console', '>= 3.3.0'
gem 'listen', '>= 3.0.5', '< 3.2'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
gem 'better_errors'
gem 'binding_of_caller'
gem 'pry-rails'
end
group :test do
# Adds support for Capybara system testing and selenium driver
gem 'capybara', '>= 2.15'
gem 'selenium-webdriver'
# Easy installation and use of chromedriver to run system tests with Chrome
gem 'chromedriver-helper'
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
routes.rb
Rails.application.routes.draw do
get '/authenticate/:type', to: 'sessions#authenticate'
get '/auth/:provider/callback', to: 'sessions#create'
root to: 'static_pages#root'
end
initializers/github.rb
Rails.application.config.middleware.use OmniAuth::Builder do
provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET']
end
sessions_controller.rb
class SessionsController < ApplicationController
def authenticate
redirect_to '/auth/github' if params[:type] == 'github'
end
def create
@user = User.find_or_create_from_oauth(auth_params)
if @user
render json: @user
else
render json: [params['error']], status: 422
end
end
private
def auth_params
request.env['omniauth.auth']
end
end
root.jsx
import React, { useState } from 'react';
import axios from 'axios';
const Root = () => {
const [name, setName] = useState('no name yet');
const githubLogin = () => {
axios.get('authenticate/github')
.then(user => setName(user.name));
}
return (
<div>
<button onClick={githubLogin}>Github Login</button>
<h1>Name: {name}</h1>
</div>
)
}
export default Root;
经过一些研究,我看到了一些添加 rack-cors
gem 的建议。我尝试这样做并添加了这个初始化程序。
initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
puts 'setting up cors'
allow do
origins '*'
resource '*', headers: :any, methods: [:get, :post, :patch, :put]
end
end
在设置 oauth 方面,我还是个新手,我正在努力弄清楚,但这让我很困惑。我不确定我的重定向是否得到 Headers 它不需要被阻止,我确定从这里去哪里。
如有任何帮助,我们将不胜感激。如果我可以提供任何其他信息,请告诉我。谢谢。
您收到错误是因为重定向发生在 XHR 的上下文中。
一个解决方案是为您的控制器创建 XHR,它会 return 一个 URL 客户端必须遵循。
另一种方法是不制作 XHR 并在您的操作中使用普通的 link。
无论哪种方式,您都应该确保您不向 JS 请求 GitHub URL。它必须是普通的 HTTP(s) 请求。