clerk / clerk-sdk-ruby

Access the Clerk Backend API from Ruby
MIT License
24 stars 10 forks source link
authentication authentication-middleware sdk sdk-ruby


# Clerk Ruby SDK This SDK allows you to call the [Clerk](https://www.clerk.com/?utm_source=github&utm_medium=starter_repos&utm_campaign=sdk_ruby) Backend API from Ruby code without having to implement the calls yourself. [![chat on Discord](https://img.shields.io/discord/856971667393609759.svg?logo=discord)](https://discord.com/invite/b5rXHjAg7A) [![documentation](https://img.shields.io/badge/documentation-clerk-green.svg)](https://clerk.com/docs) [![twitter](https://img.shields.io/twitter/follow/ClerkDev?style=social)](https://twitter.com/intent/follow?screen_name=ClerkDev) --- **Clerk is Hiring!** Would you like to work on Open Source software and help maintain this repository? [Apply today!](https://apply.workable.com/clerk-dev/) --- **Note**: You're looking at the main branch, which requires that you use [Auth v2](https://clerk.com/docs/upgrade-guides/auth-v2). If you're looking for the legacy authentication scheme, refer to the [`v1`](https://github.com/clerkinc/clerk-sdk-ruby/tree/v1) branch. ## Installation Add this line to your application's Gemfile: ```ruby gem 'clerk-sdk-ruby', require: "clerk" ``` And then execute: $ bundle install Or install it yourself as: $ gem install clerk-sdk-ruby ## Quick Start First, you need to get an API key for a Clerk instance. This is done via the [Clerk dashboard](https://dashboard.clerk.com/applications). Then you can instantiate a `Clerk::SDK` instance and access all [Backend API](https://clerk.com/docs/reference/backend-api) endpoints. Here's a quick example: ```ruby clerk = Clerk::SDK.new(api_key: "your_api_key") # List all users clerk.users.all # Get your first user user = clerk.users.all(limit: 1).first # Extract their primary email address ID email_id = user["primary_email_address_id"] # Send them a welcome email clerk.emails.create( email_address_id: email_id, from_email_name: "welcome", subject: "Welcome to MyApp", body: "Welcome to MyApp, #{user["first_name"]}", ) ``` ## Configuration The SDK can be configured in three ways: environment variables, configuration singleton and constructor arguments. The priority goes like this: 1. Constructor arguments 2. Configuration object 3. Environment variables If an argument is not provided, the configuration object is looked up, which falls back to the associated environment variable. Here's an example with all supported configuration settings their environment variable equivalents: ```ruby Clerk.configure do |c| c.api_key = "your_api_key" # if omitted: ENV["CLERK_SECRET_KEY"] - API calls will fail if unset c.base_url = "https://..." # if omitted: ENV["CLERK_API_BASE"] - defaults to "https://api.clerk.com/v1/" c.publishable_key = "pk_(test|live)_...." # if omitted: ENV["CLERK_PUBLISHABLE_KEY"] - Handshake mechanism (check section below) will fail if unset c.logger = Logger.new(STDOUT) # if omitted, no logging c.middleware_cache_store = ActiveSupport::Cache::FileStore.new("/tmp/clerk_middleware_cache") # if omitted: no caching c.excluded_routes ["/foo", "/bar/*"] end ``` You can customize each instance of the `Clerk::SDK` object by passing keyword arguments to the constructor: ```ruby clerk = Clerk::SDK.new( api_key: "X", base_url: "Y", logger: Logger.new() ) ``` For full customization, you can instead pass a `Faraday` object directly, which will ignore all the other arguments, if passed: ```ruby faraday = Faraday.new() clerk = Clerk::SDK.new(connection: faraday) ``` Refer to the [Faraday documentation](https://lostisland.github.io/faraday/usage/#customizing-faradayconnection) for details. ## Rack middleware The SDK comes with a Rack middleware which lazily loads the Clerk session and user. It inserts a `clerk` key in the Rack environment, which is an instance of `Clerk::Proxy`. To get the session or the user of the session, you call `session` or `user` respectively. In case there is no session, you can retrieve the API error with the `error` getter method. ## Rails integration The SDK will automatically add the [Rack middleware](#rack-middleware) to the middleware stack. For easier access to the Clerk session and user, include the `Clerk::Authenticatable` concern in your controller: ```ruby require "clerk/authenticatable" class ApplicationController < ActionController::Base include Clerk::Authenticatable end ``` This gives your controller and views access to the following methods: - `clerk_session` - `clerk_user` - `clerk_user_signed_in?` ## Internals The API client depends on the excellent [Faraday](https://rubygems.org/gems/faraday) gem for HTTP requests. You can swap out the original implementation with your own customized instance. The API client sends all requests as `application/x-www-form-urlencoded`. The API then responds with JSON which is then converted and returned as a Ruby `Hash`, or `Array` of hashes. Errors are also returned as a JSON object, with a single key (`errors`) containing an array of error objects. Read the [API documentation](https://clerk.com/docs/reference/backend-api) for details on expected parameters and response formats. ### Handshake The Client Handshake is a mechanism that is used to resolve a request’s authentication state from “unknown” to definitively signed in or signed out. Clerk’s session management architecture relies on a short-lived session JWT to validate requests, along with a long-lived session that is used to keep the session JWT fresh by interacting with the Frontend API. The long-lived session token is stored in an HttpOnly cookie associated with the Frontend API domain. If a short-lived session JWT is expired on a request to an application’s backend, the SDK doesn’t know if the session has ended, or if a new short-lived JWT needs to be issued. When an SDK gets into this state, it triggers the handshake. With the handshake, we can resolve the authentication state on the backend and ensure the request is properly handled as signed in or out, instead of being in a potentially “unknown” state. The handshake flow relies on redirects to exchange session information between FAPI and the application, ensuring the resolution of unknown authentication states minimizes performance impact and behaves consistently across different framework and language implementations. ## Development After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake` 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`. ## Release To release a new version: - update the version number in `version.rb` - update `CHANGELOG.md` to include information about the changes - merge changes into main - run `bundle exec rake release` If gem publishing is NOT executed automatically: - run `gem push pkg/clerk-sdk-ruby-{version}.gem` to push the `.gem` file to [rubygems.org](https://rubygems.org) The `bundle exec rake release` command: - creates a git tag with the version found in `version.rb` - pushes the git tag ## Yank release We should avoid yanking a releasing but if it's necessary execute `gem yank clerk-sdk-ruby -v {version}` ## Contributing Bug reports and pull requests are welcome on GitHub at https://github.com/clerkinc/clerk-sdk-ruby. ## License The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).