Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

token_secret_auth

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

token_secret_auth

  • 0.1.2
  • Rubygems
  • Socket score

Version published
Maintainers
1
Created
Source

TokenSecretAuth

TokenSecretAuth aims to be a simple implementation of token+secret authentication.

Clients using this can send a token + secret that looks like: { token: "koV3Zel321fe", secret: "fffixk5ptz2puaf1sk3wo5szpkrpjnhp" }

  • token is a hashed form of the model id

  • secret is randomly assigned and can be encrypted using has_secure_password or a similar implementation.

Why should I use this?

OR Why did you release this?

Many APIs use a token or a token+secret to authenticate API clients. If that token+secret grants similar power as a login+password it should be protected just like a password

However, while looking for a gem to handle mobile API authentication I found that many solutions fit into one of two categories:

  1. They required Devise
  2. They did not encrypt the token (or secret) properly

Other benefits

  • It's plain-old ruby - any model that responds to .find(id) and works with or in a manner similar to has_secure_password will work. (model instance should respond to model_instance#password=)
  • Flexible: you can send token+secret in the URL or in the header or any other way you can interpret in a controller method.

Installation

Add this line to your application's Gemfile:

gem 'token_secret_auth'

And then execute:

$ bundle

Or install it yourself as:

$ gem install token_secret_auth

In your model file add:

include TokenSecretAuth

This grants your model instances the following methods: #token, #decode_token, #generate_secret

Also add to the model:

has_secure_password

Create and run a migration to add the password_digest field to your model.
For example on rails:

$ rails generate migration AddPasswordDigestToApiClients password_digest:string

Note: you do not need a 'token' field on your model. #token is a virtual attribute derived from the model ID. password is your secret.

Usage

Getting the token

Tokens are generated from the model ID.

SomeModel.find(1000).token # => o9WM01OR1jgD
Generating a secret

Secrets are randomly generated by Model.generate_secret or #generate_secret. Store the secret using #password= or similar encrypted functionality.

client = ApiClient.find_by_token('afuoisjdjl') # or  ApiClient.new
client.password = client.generate_secret
client.save # bcrypt/has_secure_password will handle encryption

On Rails you may want to use callbacks to generate the password automatically:

  before_validation :generate_secret, on: [ :new, :create ]

Calling generate_secret on an instance will automatically set password to the new secret.

Passing token+secret to client

If your API allows a client to login and then receive a new API token+secret the responding controller method may look something like this.

 def try_login
    @email = login_params[:email]
    @pass  = login_params[:password]
    @user = User.find_by(email: @email).try(:authenticate, @pass)
    if @user
      api_client = @user.api_clients.create
      # IMPORTANT - this is the only time you can see the secret decrypted
      render json: { token: api_client.token, secret: api_client.secret }
    else
      render json: {password: ["Invalid account or password"]}, status: :unauthorized
    end
  end

To perform authentication with the token + secret, for example as a before_action in an ApplicationController:

def current_user
  if params[:credentials]
    token = credentials_params[:token]
    secret = credentials_params[:secret]
  begin
    api_client = ApiClient.authenticate_by_credentials(token, secret)
  rescue ActiveRecord::RecordNotFound
  # if someone sends a decodable token but the record doesn't exist
  end
end

  if api_client
    @current_user = api_client.user
  else
    render json: {errors: ['Unauthorized token or secret']}, status: :unauthorized }
  end
end
salt

If you'd like to change the salt used for hashing IDs to generate tokens you can add an initializer:

# config/initializers/token_secret_auth.rb

TokenSecretAuth.configure do |config|
    config.id_salt = 'some appropriately salty bytes'
end

Note: the salt used for hashing the secret (password) is controlled by your BCrypt config.

FAQ

Why not devise?

Devise is a great solution and I often recommend it. However, it is sometimes more complexity than needed for something this simple. TokenSecretAuth does not require devise.

Why do I need to encrypt my API token?

If your token or token+secret grants a user similar power as a login+password then it should be encrypted with one-way encryption just like a password.

How do I get the secret?

The secret is the password field on the model. It's only available when the instance is first created after that you can't retrieve it - - that's the whole point of one-way encryption.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/tgaff/token_secret_auth. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the TokenSecretAuth project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

FAQs

Package last updated on 20 Jan 2018

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc