steam login works

This commit is contained in:
CroneKorkN 2026-01-18 17:49:53 +01:00
parent 73e4e8a52f
commit 35cb0e2ce8
Signed by: cronekorkn
SSH key fingerprint: SHA256:v0410ZKfuO1QHdgKBsdQNF64xmTxOF8osF1LIqwTcVw
4 changed files with 96 additions and 23 deletions

View file

@ -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
# 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}"
}
}
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!"
else
redirect_to root_path, alert: "Steam authentication failed."
redirect_to root_path, alert: "Could not extract Steam ID from response."
end
else
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

View file

@ -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>

View file

@ -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