Implementing secure API for use between other internal apps
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
3
down vote
favorite
My team and I are trying to implement a secure API and would appreciate some feedback on the following:
If there are areas of improvement in the current code to improve security
Recommendations on other secure API implementations, if any, that would fit our requirements better (see below)
If there are any major loopholes in security based on this module.
Here are some requirements, considerations, and caveats:
The API clients/consumers are other web apps from our same company (internal yet public facing apps on a different sub-domain)
We'd prefer not to go the OAuth2 route. We'd like this to be a programmatic interface using key-based authentication. Basically, it will be server to server authentication.
API is already https
We'd like this to be modular/flexible enough to use across different internal apps
Please read code comments. We've gotten inspiration from multiple sources, especially the implementation of JWT in a slightly different manner.
# Inspiration from:
# - https://developers.google.com/identity/protocols/OAuth2ServiceAccount#jwt-auth
# - https://codeburst.io/jwt-to-authenticate-servers-apis-c6e179aa8c4e
# Typically, JWT's are used to provide consumer an access token after successful login.
# Considering our use case, the consumer (another internal app) will initiate the JWT
# Server will verify authenticity of request if it is able to decode JWT
# We've also set specific headers that internal apps would need to provide
module SecureAPI
# Generates a secure payload for outgoing requests
def self.secure_payload(options = , method = "get")
# Get or Post request
param_type = method == "get" ? "query" : "body"
iat = Time.now.to_i
# Reserved and Private claims
token_payload =
# The "iat" (issued at) claim identifies the time at which the JWT was issued.
iat: iat,
# Expiration
exp: iat + 60,
# Private claim
client_id: options[:client_id]
encoded_token = encode_token(token_payload, options[:shared_secret])
payload =
:headers =>
"Authorization" => "Bearer" + ' ' + encoded_token,
"JWT-Consumer" => options[:client_id]
,
param_type.to_sym =>
client_token: options[:client_token]
payload
end
# Verifies incoming requests/JWT verifier
def self.authenticate_request(request)
# Client must provide these headers
jwt_token = request.headers['Authorization'].split(' ').last
shared_secret = Rails.application.secrets[request.headers['JWT-Consumer']]
# Token must be decoded, unexpired, and verified using same hashing algo for successful auth
# else will return unauthorized response to client
decode_token(jwt_token, shared_secret)
end
def self.encode_token(payload, secret)
JWT.encode payload, secret, 'HS512'
end
def self.decode_token(token, shared_secret)
JWT.decode token, shared_secret, true, algorithm: 'HS512'
end
end
ruby security ruby-on-rails api jwt
add a comment |Â
up vote
3
down vote
favorite
My team and I are trying to implement a secure API and would appreciate some feedback on the following:
If there are areas of improvement in the current code to improve security
Recommendations on other secure API implementations, if any, that would fit our requirements better (see below)
If there are any major loopholes in security based on this module.
Here are some requirements, considerations, and caveats:
The API clients/consumers are other web apps from our same company (internal yet public facing apps on a different sub-domain)
We'd prefer not to go the OAuth2 route. We'd like this to be a programmatic interface using key-based authentication. Basically, it will be server to server authentication.
API is already https
We'd like this to be modular/flexible enough to use across different internal apps
Please read code comments. We've gotten inspiration from multiple sources, especially the implementation of JWT in a slightly different manner.
# Inspiration from:
# - https://developers.google.com/identity/protocols/OAuth2ServiceAccount#jwt-auth
# - https://codeburst.io/jwt-to-authenticate-servers-apis-c6e179aa8c4e
# Typically, JWT's are used to provide consumer an access token after successful login.
# Considering our use case, the consumer (another internal app) will initiate the JWT
# Server will verify authenticity of request if it is able to decode JWT
# We've also set specific headers that internal apps would need to provide
module SecureAPI
# Generates a secure payload for outgoing requests
def self.secure_payload(options = , method = "get")
# Get or Post request
param_type = method == "get" ? "query" : "body"
iat = Time.now.to_i
# Reserved and Private claims
token_payload =
# The "iat" (issued at) claim identifies the time at which the JWT was issued.
iat: iat,
# Expiration
exp: iat + 60,
# Private claim
client_id: options[:client_id]
encoded_token = encode_token(token_payload, options[:shared_secret])
payload =
:headers =>
"Authorization" => "Bearer" + ' ' + encoded_token,
"JWT-Consumer" => options[:client_id]
,
param_type.to_sym =>
client_token: options[:client_token]
payload
end
# Verifies incoming requests/JWT verifier
def self.authenticate_request(request)
# Client must provide these headers
jwt_token = request.headers['Authorization'].split(' ').last
shared_secret = Rails.application.secrets[request.headers['JWT-Consumer']]
# Token must be decoded, unexpired, and verified using same hashing algo for successful auth
# else will return unauthorized response to client
decode_token(jwt_token, shared_secret)
end
def self.encode_token(payload, secret)
JWT.encode payload, secret, 'HS512'
end
def self.decode_token(token, shared_secret)
JWT.decode token, shared_secret, true, algorithm: 'HS512'
end
end
ruby security ruby-on-rails api jwt
add a comment |Â
up vote
3
down vote
favorite
up vote
3
down vote
favorite
My team and I are trying to implement a secure API and would appreciate some feedback on the following:
If there are areas of improvement in the current code to improve security
Recommendations on other secure API implementations, if any, that would fit our requirements better (see below)
If there are any major loopholes in security based on this module.
Here are some requirements, considerations, and caveats:
The API clients/consumers are other web apps from our same company (internal yet public facing apps on a different sub-domain)
We'd prefer not to go the OAuth2 route. We'd like this to be a programmatic interface using key-based authentication. Basically, it will be server to server authentication.
API is already https
We'd like this to be modular/flexible enough to use across different internal apps
Please read code comments. We've gotten inspiration from multiple sources, especially the implementation of JWT in a slightly different manner.
# Inspiration from:
# - https://developers.google.com/identity/protocols/OAuth2ServiceAccount#jwt-auth
# - https://codeburst.io/jwt-to-authenticate-servers-apis-c6e179aa8c4e
# Typically, JWT's are used to provide consumer an access token after successful login.
# Considering our use case, the consumer (another internal app) will initiate the JWT
# Server will verify authenticity of request if it is able to decode JWT
# We've also set specific headers that internal apps would need to provide
module SecureAPI
# Generates a secure payload for outgoing requests
def self.secure_payload(options = , method = "get")
# Get or Post request
param_type = method == "get" ? "query" : "body"
iat = Time.now.to_i
# Reserved and Private claims
token_payload =
# The "iat" (issued at) claim identifies the time at which the JWT was issued.
iat: iat,
# Expiration
exp: iat + 60,
# Private claim
client_id: options[:client_id]
encoded_token = encode_token(token_payload, options[:shared_secret])
payload =
:headers =>
"Authorization" => "Bearer" + ' ' + encoded_token,
"JWT-Consumer" => options[:client_id]
,
param_type.to_sym =>
client_token: options[:client_token]
payload
end
# Verifies incoming requests/JWT verifier
def self.authenticate_request(request)
# Client must provide these headers
jwt_token = request.headers['Authorization'].split(' ').last
shared_secret = Rails.application.secrets[request.headers['JWT-Consumer']]
# Token must be decoded, unexpired, and verified using same hashing algo for successful auth
# else will return unauthorized response to client
decode_token(jwt_token, shared_secret)
end
def self.encode_token(payload, secret)
JWT.encode payload, secret, 'HS512'
end
def self.decode_token(token, shared_secret)
JWT.decode token, shared_secret, true, algorithm: 'HS512'
end
end
ruby security ruby-on-rails api jwt
My team and I are trying to implement a secure API and would appreciate some feedback on the following:
If there are areas of improvement in the current code to improve security
Recommendations on other secure API implementations, if any, that would fit our requirements better (see below)
If there are any major loopholes in security based on this module.
Here are some requirements, considerations, and caveats:
The API clients/consumers are other web apps from our same company (internal yet public facing apps on a different sub-domain)
We'd prefer not to go the OAuth2 route. We'd like this to be a programmatic interface using key-based authentication. Basically, it will be server to server authentication.
API is already https
We'd like this to be modular/flexible enough to use across different internal apps
Please read code comments. We've gotten inspiration from multiple sources, especially the implementation of JWT in a slightly different manner.
# Inspiration from:
# - https://developers.google.com/identity/protocols/OAuth2ServiceAccount#jwt-auth
# - https://codeburst.io/jwt-to-authenticate-servers-apis-c6e179aa8c4e
# Typically, JWT's are used to provide consumer an access token after successful login.
# Considering our use case, the consumer (another internal app) will initiate the JWT
# Server will verify authenticity of request if it is able to decode JWT
# We've also set specific headers that internal apps would need to provide
module SecureAPI
# Generates a secure payload for outgoing requests
def self.secure_payload(options = , method = "get")
# Get or Post request
param_type = method == "get" ? "query" : "body"
iat = Time.now.to_i
# Reserved and Private claims
token_payload =
# The "iat" (issued at) claim identifies the time at which the JWT was issued.
iat: iat,
# Expiration
exp: iat + 60,
# Private claim
client_id: options[:client_id]
encoded_token = encode_token(token_payload, options[:shared_secret])
payload =
:headers =>
"Authorization" => "Bearer" + ' ' + encoded_token,
"JWT-Consumer" => options[:client_id]
,
param_type.to_sym =>
client_token: options[:client_token]
payload
end
# Verifies incoming requests/JWT verifier
def self.authenticate_request(request)
# Client must provide these headers
jwt_token = request.headers['Authorization'].split(' ').last
shared_secret = Rails.application.secrets[request.headers['JWT-Consumer']]
# Token must be decoded, unexpired, and verified using same hashing algo for successful auth
# else will return unauthorized response to client
decode_token(jwt_token, shared_secret)
end
def self.encode_token(payload, secret)
JWT.encode payload, secret, 'HS512'
end
def self.decode_token(token, shared_secret)
JWT.decode token, shared_secret, true, algorithm: 'HS512'
end
end
ruby security ruby-on-rails api jwt
edited Jun 26 at 5:58
yuri
3,3872832
3,3872832
asked Jun 26 at 4:08
Katherine Eugenio
161
161
add a comment |Â
add a comment |Â
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f197247%2fimplementing-secure-api-for-use-between-other-internal-apps%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password