steam login works
This commit is contained in:
parent
73e4e8a52f
commit
35cb0e2ce8
4 changed files with 96 additions and 23 deletions
|
|
@ -1,22 +1,89 @@
|
|||
require "net/http"
|
||||
|
||||
class SessionsController < ApplicationController
|
||||
skip_before_action :authenticate_user!
|
||||
skip_before_action :authenticate_user!, only: [ :auth_request, :steam_callback ]
|
||||
|
||||
def auth_request
|
||||
# Manually trigger OmniAuth Steam strategy
|
||||
request.env['omniauth.strategy'] = OmniAuth::Strategies::Steam.new(nil)
|
||||
auth = request.env['omniauth.strategy'].request_phase
|
||||
redirect_to auth
|
||||
# Build Steam OpenID URL
|
||||
steam_openid_url = "https://steamcommunity.com/openid/login"
|
||||
# Use the actual request host/protocol for both return_to and realm to avoid signature mismatch
|
||||
base_url = request.base_url
|
||||
return_url = "#{base_url}#{steam_callback_path}"
|
||||
|
||||
Rails.logger.info("Steam auth_request return_url=#{return_url} realm=#{base_url}")
|
||||
|
||||
params = {
|
||||
"openid.ns" => "http://specs.openid.net/auth/2.0",
|
||||
"openid.identity" => "http://specs.openid.net/auth/2.0/identifier_select",
|
||||
"openid.claimed_id" => "http://specs.openid.net/auth/2.0/identifier_select",
|
||||
"openid.mode" => "checkid_setup",
|
||||
"openid.return_to" => return_url,
|
||||
"openid.realm" => base_url,
|
||||
"openid.ns.sreg" => "http://openid.net/extensions/sreg/1.1",
|
||||
"openid.sreg.required" => "email"
|
||||
}
|
||||
|
||||
redirect_to "#{steam_openid_url}?#{params.to_query}", allow_other_host: true
|
||||
end
|
||||
|
||||
def steam_callback
|
||||
auth_hash = request.env["omniauth.auth"]
|
||||
# Get the OpenID response
|
||||
openid_response = request.params
|
||||
|
||||
if auth_hash
|
||||
user = User.find_or_create_from_steam(auth_hash)
|
||||
session[:user_id] = user.id
|
||||
redirect_to dashboard_path, notice: "Logged in successfully!"
|
||||
# Verify the response with Steam
|
||||
if verify_steam_response(openid_response)
|
||||
# Extract Steam ID from identity URL
|
||||
# Format: http://steamcommunity.com/openid/id/[STEAMID]
|
||||
identity_url = openid_response["openid.identity"]
|
||||
|
||||
if identity_url && identity_url.include?("/id/")
|
||||
steam_id = identity_url.split("/id/").last
|
||||
|
||||
# Create mock auth_hash for compatibility with our User model
|
||||
auth_hash = {
|
||||
"uid" => steam_id,
|
||||
"info" => {
|
||||
"nickname" => "Steam User #{steam_id}"
|
||||
}
|
||||
}
|
||||
|
||||
user = User.find_or_create_from_steam(auth_hash)
|
||||
session[:user_id] = user.id
|
||||
redirect_to dashboard_path, notice: "Logged in successfully!"
|
||||
else
|
||||
redirect_to root_path, alert: "Could not extract Steam ID from response."
|
||||
end
|
||||
else
|
||||
redirect_to root_path, alert: "Steam authentication failed."
|
||||
redirect_to root_path, alert: "Steam authentication failed: Invalid response signature."
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def verify_steam_response(response)
|
||||
# Steam expects only openid.* keys and mode=check_auth for validation
|
||||
openid_params = response.to_h.select { |k, _| k.to_s.start_with?("openid.") }
|
||||
return false unless openid_params["openid.mode"] == "id_res"
|
||||
|
||||
# Per OpenID 2.0 spec, the verification mode is "check_authentication"
|
||||
verify_params = openid_params.merge("openid.mode" => "check_authentication")
|
||||
|
||||
Rails.logger.info("Steam verify payload: #{verify_params.inspect}")
|
||||
|
||||
uri = URI.parse("https://steamcommunity.com/openid/login")
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
http.use_ssl = true
|
||||
|
||||
request = Net::HTTP::Post.new(uri.path)
|
||||
request.set_form_data(verify_params)
|
||||
|
||||
begin
|
||||
response = http.request(request)
|
||||
Rails.logger.info("Steam verify response body: #{response.body.inspect}")
|
||||
response.body.include?("is_valid:true")
|
||||
rescue StandardError => e
|
||||
Rails.logger.error("Steam verification error: #{e.message}")
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -24,4 +91,8 @@ class SessionsController < ApplicationController
|
|||
session[:user_id] = nil
|
||||
redirect_to root_path, notice: "Logged out successfully!"
|
||||
end
|
||||
|
||||
def omniauth_failure
|
||||
redirect_to root_path, alert: "Steam authentication failed: #{params[:message]}"
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -24,6 +24,13 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<% if flash.any? %>
|
||||
<div class="flash-messages">
|
||||
<% flash.each do |type, message| %>
|
||||
<div class="flash flash-<%= type %>"><%= message %></div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= yield %>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,2 @@
|
|||
Rails.application.config.middleware.use OmniAuth::Builder do
|
||||
provider :steam, ENV["STEAM_API_KEY"] || "test"
|
||||
end
|
||||
|
||||
OmniAuth.config.on_failure = proc { |env|
|
||||
OmniAuth::FailureEndpoint.new(env).redirect_to_failure
|
||||
}
|
||||
# OmniAuth is not used - we implement direct Steam OpenID 2.0 protocol
|
||||
# This file is kept for reference but the middleware is disabled
|
||||
|
|
|
|||
Loading…
Reference in a new issue