Forked from sobstel/app-controllers-concerns-authenticable.rb
Created
May 10, 2019 11:20
-
-
Save phlegx/cf3cd8a6c6361ff5a8d5198355ac5dd9 to your computer and use it in GitHub Desktop.
Rails, Auth0, JWT, RS256
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Authenticable | |
extend ActiveSupport::Concern | |
# Filter to use with before_action | |
def authenticate_user | |
jwt_token | |
rescue JWT::DecodeError => e | |
render json: { error: e.message }, status: :unauthorized | |
end | |
# @return [User|nil] | |
def current_user | |
@current_user ||= User.new jwt_token.try(:first) | |
rescue JWT::DecodeError | |
nil | |
end | |
private | |
def jwt_token | |
bearer = request.env.fetch('HTTP_AUTHORIZATION', '').slice(7..-1) | |
rsa_public_key = OpenSSL::PKey::RSA.new( | |
OpenSSL::X509::Certificate.new( | |
Rails.configuration.auth0['signing_certificate'] | |
).public_key | |
) | |
JWT.decode bearer, rsa_public_key, true, algorithm: 'RS256' | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module App | |
class Application < Rails::Application | |
# (...) | |
config.auth0 = config_for(:auth0) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
production: &default | |
# taken from auth0.com: Clients > AppJobs > Settings > Advanced Settings > Certificates | |
signing_certificate: | | |
-----BEGIN CERTIFICATE----- | |
... | |
-----END CERTIFICATE----- | |
development: | |
<<: *default | |
test: | |
<<: *default | |
# generated with `openssl req -x509 -newkey rsa:2048 -keyout privatekey.pem -out certificate.pem` | |
signing_certificate: | | |
-----BEGIN CERTIFICATE----- | |
MIIDtTCCAp2gAwIBAgIJAPunMNM1vt7wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV | |
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX | |
aWRnaXRzIFB0eSBMdGQwHhcNMTcwMjA5MDk1MTEzWhcNMTcwMzExMDk1MTEzWjBF | |
MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 | |
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB | |
CgKCAQEAnEUQtIH4cmK9j41CC5tyk0v8CJNC803ie4vJPaYIc8Q4UXhnndi5mjb/ | |
ao4ZjmQoJPTSpPKlBQ9u7zuq2O52usXn977Pe6c2p1gXNC6a1pDB0BWxZ3IdfqyF | |
rwyunPCJ4XtTSz59noD42/BaZXKq808ToR04IMpSfgTgl8uYExXTs4cFpCdN3YB9 | |
e3/KuDN77Wl4ReWNhWb2v9Y/J0j8D4yYOTatYEPHnGm2EvvoeNoNhfb+kM4Bh5f1 | |
fudZUjclX8fJ0dVkesGtpbe3qK/+QtncJHAXC3P1GRFr+fGK9Iytrl6Mv6SVFZ4R | |
yArqgU0YZwvP+dNac9KAOgOEelmZZQIDAQABo4GnMIGkMB0GA1UdDgQWBBTMTFdM | |
XXO4RgdUSeIVG8yy2trHZzB1BgNVHSMEbjBsgBTMTFdMXXO4RgdUSeIVG8yy2trH | |
Z6FJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV | |
BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAPunMNM1vt7wMAwGA1UdEwQF | |
MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAGQNo4QmtPHf+ZdspVFsTqi+7slZb0it | |
b2zyB8xYv6AyX9bAeGBYIqw9ObuRWL8IW3mGb/MDgKyoeydHPBf8GHJRf5GVXMJz | |
7cnY1HJz+v+R+Em2bMqlsuRr0NTD7/vGUptuzYVtpJQXfwtLDHTZRvYXuLwr8x2o | |
LFtRPjsmI7LvUhvAK5bm7zhPULrVcZZdITRKHw1eePebPxDm2Z3zzUHLgfwnR8CH | |
nJMBQ1R0Uk7SbXo8hjJY7fpMB7UMk8O1urE5i5poBhjdw8e62EfpidSQTrMsmt+F | |
LCG0/53nHkYRfJNWh5YeMptEkbJfbM3JKU2MiWrZRmdJVR+0B06TnDY= | |
-----END CERTIFICATE----- | |
private_key: | | |
-----BEGIN RSA PRIVATE KEY----- | |
Proc-Type: 4,ENCRYPTED | |
DEK-Info: DES-EDE3-CBC,F4FD7F790446D8BA | |
zIHjysaSGXoaZucd33SIc5jt8JG0iB6d8cokxFnsy8JlsIfRaWqz+CDlN2TpTHjH | |
AOtV+c9Dhv8I8teCmwxzGy2XOHWY909UrhwIT3xM10OiGMwEnVJ90eBKdcGEZZUX | |
TnLNAM+Ip44+beRpGOya56PzoNSIE5W7CCexlZ4L/vvPhHb7jb33QoUq3EIFW1+6 | |
xpLW8Imf61X1QCZizbBU9GMg71FqePW+X1OfwQIMX7V1lCDeTQuA5BwCT+wapFVV | |
m95lPvaiDkz44V7kGvREPzpgQvFdvRe6oShEEfvlmSylQtYv5568FymWlBKtkmTh | |
69pJZZ4jdGTU+CI5IOP2tEiLRRQYh81bd8KY027RO9buZWSB8GeNOT+6V/B/Uy7G | |
x5vt1/CGhZHnEFLFHNHMObF7PMyDZhuYGYz3aH5G/Asb9Z+W+XgeIWOIofP3Vfq7 | |
0z3BfoCmwZcU+GfFfLDxkHep+QvEjc4Ax8j7vMq0E2vzzqIijVDOJHC0X7ZJF8qQ | |
lH137SBDnVLSspJSlqKOD5iuYQBPdchprE/+3CRZwjRXsPcwJ9IjiLtUSBvEkgd2 | |
EmW18LgoTj7Rt8aWtx4PtgL/0eNKoKnxuHGeXWNyczh9/8BbeQT0s5I098QHJ2+w | |
VyWXl7qyfQDSvt6ARi+D1R/mL/AGkIEWetZmokYewfubcumw9dG1f78IDrLzQ3Ew | |
bk8dKjeeFqb0A5ZWcSmcgWYo03n2GtmKKT/ag/CCkUUmK4GSxIldQ4XnntalrKtJ | |
4kEBrHRPSJQpXz/hFg90E7Ct1EwhEIqdvBB9005DyQZMGIY8uAwCOsKy3tiyrGaS | |
4t6vzxGB7BsZVsi2EwK/gGTdLgiHD6CJyOLrHdeihBqnDO/zmNVamlaKpqUnjrIT | |
YQQDlc4Dhm/+jutyFsrXjQNiOKGVxAtXlkYmLj0fXwH3zsdpvTTOWktIdAn0Nhg7 | |
N3rAl3TDsF7lBhDf6Aa9n9jvdp9lzhRRy0buvCBjvO99c6PWFgcOXJtdmoIwyoGq | |
i3/8rQTTb+gp/yjnTguXoSqDpGLCtb6fM6B0ER0F/uypyXWBi9U0pcVrJ+7wETye | |
8+a0Yj7Lc18S/IilWLI0a0pJEeWXJDlsICkFfYMRmm2WG/4NfHFH9GiEVN71AVQt | |
+r1j68kDiZdgSFI/tlw9G+fN3jcJVQ4grg4w6RnP5xSWdp7fJFH1pft6WfZy4n6f | |
xiFId8Cl81lJ4ptMh+kib0usR0i2zwDK8fSYIr3RmOOw3G4monSDrKGNSpVTImDD | |
pAI0B+AxzGU+p1v0PasQ72wLv5fx21yOZTlS/c2dC6qlfPDqUXT1PY8O4Yz1hhUS | |
bGujavaIenPmeFVtE/io3M5Ge+Nzv6Rt9zvuXJfrxpwnK5X6gI2mTPv0rCXrGODG | |
YUfGSiexYkFMSu+gZNbwg7SL715wM5Np7evJcpvALqwvLRuHlWE/7gR6vC0ywg0N | |
Sg8NRheEdP2LIejRXqQ5l73w3A4wSzEgipdrH4azQBWUh6F7eCLjfOjC80lRosT+ | |
IidiK9THkzZykLlKrfuT2VaSEjmVg6vpamTG/fu6fea+35MnY6Aq1g== | |
-----END RSA PRIVATE KEY----- | |
private_key_passphrase: appjobs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Helpers | |
def current_user_headers(payload_overwrites = {}) | |
payload = { | |
email: '[email protected]', | |
email_verified: true, | |
nickname: 'Current User', | |
iss: 'https://YOURAPP.auth0.com/', | |
sub: 'auth0|123456789', | |
aud: 'YOUR_AUD', | |
exp: (Time.now + 1.day).to_i, | |
iat: Time.now.to_i | |
}.merge(payload_overwrites) | |
@private_key ||= OpenSSL::PKey::RSA.new( | |
Rails.configuration.auth0['private_key'], | |
Rails.configuration.auth0['private_key_passphrase'] | |
) | |
id_token = JWT.encode payload, @private_key, 'RS256' | |
{ 'Authorization' => "Bearer #{id_token}" } | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rails_helper' | |
describe 'User' do | |
specify 'current user info', do | |
get '/user', headers: current_user_headers | |
expect(response).to be_success | |
expect(response.body).to have_json_size(8) | |
expect(response.body).to be_json_eql('Current User'.to_json).at_path('nickname') | |
expect(response.body).to be_json_eql('[email protected]'.to_json).at_path('email') | |
end | |
specify 'jwt: signature has expired' do | |
get '/user', headers: current_user_headers(exp: Time.now - 1.day) | |
expect(response).not_to be_success | |
expect(response.body).to have_json_size(1) | |
expect(response.body).to be_json_eql('Signature has expired'.to_json).at_path('error') | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment