- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
问题
当我尝试验证从 Apple SSO 客户端流程返回的 code
时,我不断收到 unsupported_grant_type
400 错误。
docs假设当经过身份验证的客户端无权使用授权类型时,将返回
我已在 App Id、Service Id 上启用 Apple SSO,并且甚至验证了我的支持电子邮件域。我缺少什么?我还需要完成其他审批步骤才能获得授权吗?unsupported_grant_type
。
我尝试从验证请求中删除参数,但仍然收到相同的错误代码。
详细信息
SSO 重定向为我提供了一个表单编码的 POST 正文,如下所示:{"state"=>"x", "code"=>"y", "id_token"=>"z"}
.
然后,我尝试通过调用 validate_auth_token
来验证 token 。
def validate_auth_token(token, is_refresh = false)
uri = URI.parse('https://appleid.apple.com/auth/token')
https = Net::HTTP.new(uri.host, uri.port)
https.use_ssl = true
headers = { 'Content-Type': 'text/json' }
request = Net::HTTP::Post.new(uri.path, headers)
request_body = {
client_id: @client_id,
client_secret: retreive_client_secret
}
if is_refresh
request_body[:grant_type] = 'refresh_token'
request_body[:refresh_token] = token
else
request_body[:grant_type] = 'authorization_code'
request_body[:code] = token
request_body[:redirect_uri] = "https://#{Rails.application.secrets.backend_host_port}/apple"
end
request.body = request_body.to_json
response = https.request(request)
p JSON.parse response.body
end
def retreive_client_secret
cert = retreive_secret_cert
ecdsa_key = OpenSSL::PKey::EC.new cert
algorithm = 'ES256'
headers = {
'alg': algorithm,
'kid': @key_id
}
claims = {
'iss': @team_id,
'iat': Time.now.to_i,
'exp': Time.now.to_i + 5.months.to_i,
'aud': 'https://appleid.apple.com',
'sub': @client_id
}
token = JWT.encode claims, ecdsa_key, algorithm, headers
token
end
其中@client_id是我在初始SSO请求中提交的“服务ID”,@key_id是从Apple Key仪表板下载的私钥的ID,@team_id是我们的Apple团队ID。 retrieve_secret_cert
只是获取用于生成客户端 key 的证书文件正文。
考虑到这一切,我预计 TokenResponse ,但不断收到相同的错误 {"error"=>"unsupported_grant_type"}
且没有任何其他解释。
最佳答案
token 验证请求需要采用form编码,而不是json编码。此外,当我在 JWT 中包含 alg
header 时,请求无法正确验证,但在删除它后可以正常工作。
这是更新后的代码:
def validate_auth_token(token, is_refresh = false)
uri = URI.parse('https://appleid.apple.com/auth/token')
https = Net::HTTP.new(uri.host, uri.port)
https.use_ssl = true
request_body = {
client_id: @client_id,
client_secret: retreive_client_secret
}
if is_refresh
request_body[:grant_type] = 'refresh_token'
request_body[:refresh_token] = token
else
request_body[:grant_type] = 'authorization_code'
request_body[:code] = token
request_body[:redirect_uri] = "https://#{Rails.application.secrets.backend_host_port}/auth"
end
request = Net::HTTP::Post.new(uri.path)
request.set_form_data(request_body)
response = https.request(request)
JSON.parse response.body
end
def retreive_client_secret
cert = retreive_secret_cert
ecdsa_key = OpenSSL::PKey::EC.new cert
algorithm = 'ES256'
headers = {
'kid': @key_id
}
claims = {
'iss': @team_id,
'iat': Time.now.to_i,
'exp': Time.now.to_i + 5.minutes.to_i,
'aud': 'https://appleid.apple.com',
'sub': @client_id
}
token = JWT.encode claims, ecdsa_key, algorithm, headers
token
end
谢谢sudhakar19用于指出编码错误。
关于ios - 苹果单点登录 : Why I am getting a 'unsupported_grant_type' error?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57861466/
我是一名优秀的程序员,十分优秀!