Maya Workflow Kit
Blender에서 Maya 전체 워크플로를 한 번에 설치, 무료 오픈소스, Blender 4.5‑5.2 지원
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Devise::Webauthn is a Devise extension that adds WebAuthn support to your Rails application, allowing users to authenticate with passkeys and use security keys for two factor authentication.
Add this line to your application's Gemfile:
gem 'devise-webauthn'
And then execute:
$ bundle install
Or install it yourself as:
$ gem install devise-webauthn
First, ensure you have Devise set up in your Rails application. For a full guide on setting up Devise, refer to the Devise documentation. Then, follow these steps to integrate Devise::Webauthn:
Run Devise::Webauthn Generator: Run the generator to set up necessary configurations and migrations:
$ bin/rails generate devise:webauthn:install
You can optionally specify a different resource name (defaults to "user"):
$ bin/rails generate devise:webauthn:install --resource-name=RESOURCE_NAME
The generator will:
config/initializers/webauthn.rb)WebauthnCredential model and migrationwebauthn_id field to your devise model (e.g., User)Run Migrations: After running the generator, execute the migrations to update your database schema:
$ bin/rails db:migrate
Update Your Devise Model:
Add :passkey_authenticatable to your Devise model (e.g., User) for passkeys authentication and :webauthn_two_factor_authenticatable for WebAuthn-based 2FA if desired. For example:
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
:passkey_authenticatable, :webauthn_two_factor_authenticatable
end
Configure WebAuthn Settings:
Update the generated initializer file config/initializers/webauthn.rb with your application's specific settings, such as rp_name, and allowed_origins. For example:
WebAuthn.configure do |config|
# This value needs to match `window.location.origin` evaluated by
# the User Agent during registration and authentication ceremonies.
config.allowed_origins = ["https://yourapp.com"]
# Relying Party name for display purposes
config.rp_name = "Your App Name"
end
[!TIP] You can find a working example on how to use this gem for passwordless and two factor authentication in
devise-webauthn-rails-demo.
Include bundled WebAuthn JavaScript in your application: The install generator automatically configures JavaScript loading based on your setup:
For importmap-rails:
pin "devise/webauthn", to: "devise/webauthn.js" to config/importmap.rbimport "devise/webauthn" to app/javascript/application.jsFor node setups (esbuild, Bun, etc.):
<%= javascript_include_tag "devise/webauthn" %> to your application layoutIf the automatic setup doesn't work for your configuration, you can manually include the JavaScript:
<%= javascript_include_tag "devise/webauthn" %>
When the form is submitted:
Signed-in users can add passkeys by visiting /users/passkeys/new.
When a user visits /users/sign_in they can choose to authenticate using a passkey. The authentication flow is handled by PasskeysAuthenticatable strategy.
The WebAuthn passkey sign-in flow works as follows:
Signed-in users can add security keys by visiting /users/second_factor_webauthn_credentials/new.
When a user that has 2FA enabled (i.e., has registered passkeys or security keys) visits /users/sign_in, after entering their primary credentials (e.g., email and password), they will be prompted to complete the second factor authentication using WebAuthn. The authentication flow is handled by WebauthnTwoFactorAuthenticatable strategy.
In a browser, the two factor authentication flow with WebAuthn works as follows:
[!NOTE] API clients are not redirected. Their password sign-in responds
401, and they complete the second factor with JSON requests. See Two-factor sign-in for API clients.
By default, WebAuthn challenges are kept in the session between the options request and the sign-in or registration request. To keep them in a cache instead:
# config/initializers/devise_webauthn.rb
Devise::Webauthn.challenge_store = :cache
# Optional. Defaults to Rails.cache and 5 minutes.
Devise::Webauthn::ChallengeStores::Cache.cache = Rails.cache
Devise::Webauthn::ChallengeStores::Cache.expires_in = 5.minutes
Each challenge can be used once. The two requests can reach different servers or processes, so use a cache shared by all your servers (Redis, Memcached or Solid Cache). ActiveSupport::Cache::MemoryStore and FileStore are local to one process or host.
Mobile apps and other API clients can use passkeys and security keys without a session cookie. They authenticate each request with a token instead, for example with devise-jwt.
:cache challenge store with a cache shared by all your servers:
# config/initializers/devise_webauthn.rb
Devise::Webauthn.challenge_store = :cache
# config/initializers/devise.rb
config.skip_session_storage = [:http_auth, :params_auth]
config.parent_controller, ApplicationController by default). Send Accept: application/json from the client.
class ApplicationController < ActionController::Base
respond_to :html, :json
end
ActionController::API, use respond_to :json, and set config.navigational_formats = [] in the Devise initializer. Otherwise a request without an Accept header counts as a browser request, and Devise raises when it writes to the session.:registerable, override sign_up in your registrations controller to call sign_in(resource_name, resource, store: false). Devise's default writes to the session.WebAuthn.configure do |config|
config.rp_id = "example.com"
config.allowed_origins = [
"https://example.com", # web and iOS
"android:apk-key-hash:<base64url SHA-256 of your signing certificate>"
]
end
Your domain must also serve /.well-known/apple-app-site-association (with webcredentials) and /.well-known/assetlinks.json (with delegate_permission/common.get_login_creds).POST /users/sign_in by default. Add the two-factor path:
config.jwt do |jwt|
jwt.dispatch_requests = [["POST", %r{^/users/two_factor_authentication$}]]
end
Send public_key_credential as the JSON object your WebAuthn library returns. For a resource named user:
| Step | Request | Response |
|---|---|---|
| Sign-in options | POST /users/passkey_authentication_options | WebAuthn request options |
| Sign in | POST /users/sign_in with public_key_credential | 201, and a JWT when you use devise-jwt |
| Registration options | POST /users/passkey_registration_options (authenticated) | WebAuthn creation options |
| Add passkey | POST /users/passkeys with name and public_key_credential (authenticated) | 201, or 422 with errors |
| Delete passkey | DELETE /users/passkeys/:id (authenticated) | 204 |
| Security key registration options | POST /users/security_key_registration_options (authenticated) | WebAuthn creation options |
| Add security key | POST /users/second_factor_webauthn_credentials with name and public_key_credential (authenticated) | 201, or 422 with errors |
| Promote security key to passkey | PATCH /users/second_factor_webauthn_credentials/:id (authenticated) | 204 |
| Delete security key | DELETE /users/second_factor_webauthn_credentials/:id (authenticated) | 204 |
When a user has 2FA enabled, password sign-in takes three requests:
POST /users/sign_in with the email and password. The response is 401 with error and two_factor_token.POST /users/security_key_authentication_options with two_factor_token. The response has the WebAuthn request options.POST /users/two_factor_authentication with two_factor_token and public_key_credential. The response is 201, and a JWT when you use devise-jwt.About the two_factor_token:
filter_parameters so Rails does not log it.Devise::Webauthn::TwoFactorToken.expires_in).skip_session_storage includes :params_auth. Otherwise the session keeps the pending sign-in, and the client sends no token.Similar to views customization on Devise, to customize the views, you can copy the view files from the gem into your application. Run the following command:
$ bin/rails generate devise:webauthn:views
If you want to customize only specific views, you can copy them individually. For example, to copy only the passkeys views:
$ bin/rails generate devise:webauthn:views -v passkeys
Devise::Webauthn provides helpers that can be used in your views. These helpers accept either a resource name (e.g., :user) or a resource object (e.g., @user) as the first argument.
For example, for a resource named user, you can use the following helpers:
To add a form for logging in with passkeys:
<%= login_with_passkey_form_for(:user) do |form| %>
<%= form.submit "Log in with passkeys" %>
<% end %>
To add a form for logging in with security keys (2FA):
<%= login_with_security_key_form_for(@resource) do |form| %>
<%= form.submit "Use security key" %>
<% end %>
To add a passkeys creation form:
<%= passkey_creation_form_for(:user) do |form| %>
<%= form.label :name, 'Passkey name' %>
<%= form.text_field :name, required: true %>
<%= form.submit 'Create Passkey' %>
<% end %>
The custom elements check for WebAuthn API support when they connect to the DOM. If the browser doesn't support WebAuthn, a webauthn:unsupported event is dispatched and the form submission handler is not attached.
document.addEventListener('webauthn:unsupported', (event) => {
const { action } = event.detail; // 'create' or 'get'
// Hide the WebAuthn form and show a message
hideWebauthnFormWithMessage('Your browser does not support WebAuthn');
});
By default, WebAuthn errors during registration or authentication are displayed using the browser's alert() dialog. You can customize this behavior by listening to the webauthn:prompt:error event.
The custom elements dispatch a webauthn:prompt:error event whenever an error occurs during the WebAuthn prompt interaction (registration or authentication). You can listen for this event and provide custom error handling:
document.addEventListener('webauthn:prompt:error', (event) => {
event.preventDefault(); // Prevent the default alert
const { error, action } = event.detail;
// Your custom error handling
console.error(`WebAuthn ${action} failed:`, error);
showFlashMessage(error.message, 'error');
});
The event includes the following information in event.detail:
error: The error object thrown during the WebAuthn operationaction: Either "create" (for registration) or "get" (for authentication)WebAuthn operations can fail for various reasons. Here are some common error types you might want to handle:
document.addEventListener('webauthn:prompt:error', (event) => {
event.preventDefault();
const { error, action } = event.detail;
switch (error.name) {
case 'NotAllowedError':
// User cancelled the operation or timeout
showFlashMessage('Operation cancelled or timed out', 'warning');
break;
default:
// Generic error message
showFlashMessage(`Authentication error: ${error.message}`, 'error');
}
});
You can provide different error handling based on whether the error occurred during registration or authentication:
document.addEventListener('webauthn:prompt:error', (event) => {
event.preventDefault();
const { error, action } = event.detail;
if (action === 'create') {
// Handle registration errors
handleRegistrationError(error);
} else if (action === 'get') {
// Handle authentication errors
handleAuthenticationError(error);
}
});
Note: If you don't call event.preventDefault(), the default alert() will still be shown.
Similar to controllers customization on Devise, you can customize the Devise::Webauthn controllers.
$ bin/rails generate devise:webauthn:controllers [scope]
users:devise_for :users, controllers: {
passkeys: 'users/passkeys'
}
When a passkey or a security key is added, the registration options send webauthn_user_name as both the WebAuthn user.name and user.displayName. A passkey keeps this name, and the browser or operating system shows it when the user picks a passkey to sign in.
By default it is the first authentication key with a non-nil value, such as the email. If that key is nil on a saved record, such as a plain attr_accessor :login, override webauthn_user_name in your model:
class User < ApplicationRecord
devise :database_authenticatable, :passkey_authenticatable, authentication_keys: [:login]
attr_accessor :login
def webauthn_user_name
username.presence || email
end
end
The method must return a non-blank string. If it returns nil, the registration options have no name or displayName, PublicKeyCredential.parseCreationOptionsFromJSON throws a TypeError in the browser, and the user cannot add the passkey or security key.
The gem provides two custom HTML elements for WebAuthn operations. While the form helpers handle this automatically, you can use these elements directly for custom implementations.
<webauthn-create>Used for registering new credentials (passkeys or security keys).
<form action="/passkeys" method="post">
<webauthn-create data-options-url="<%= passkey_registration_options_path(:user) %>">
<input type="hidden" name="public_key_credential" data-webauthn-target="response">
<input type="text" name="name" placeholder="Passkey name">
<button type="submit">Create Passkey</button>
</webauthn-create>
</form>
Requirements:
<form> element
passkeys_path(resource_name)second_factor_webauthn_credentials_path(resource_name)data-options-url attribute pointing to the endpoint serving the WebAuthn creation options – you can use the provided url helpers:
passkey_registration_options_path(resource_name)security_key_registration_options_path(resource_name)data-webauthn-target="response" to store the credential response<webauthn-get>Used for authenticating with existing credentials.
<form action="/users/sign_in" method="post">
<webauthn-get data-options-url="<%= passkey_authentication_options_path(:user) %>">
<input type="hidden" name="public_key_credential" data-webauthn-target="response">
<button type="submit">Sign in with Passkey</button>
</webauthn-get>
</form>
Requirements:
<form> element
session_path(resource_name)two_factor_authentication_path(resource_name)data-options-url attribute pointing to the endpoint serving the WebAuthn request options – you can use the provided url helpers:
passkey_authentication_options_path(resource_name)security_key_authentication_options_path(resource_name)data-webauthn-target="response" to store the credential responseAfter checking out the repo, run bin/setup to install dependencies. Then, run bundle exec rspec to run the tests.
To run the linter, use bundle exec rubocop.
Before submitting a pull request, ensure that tests and linter pass.
Bug reports and pull requests are welcome on GitHub at https://github.com/cedarcode/devise-webauthn.
The gem is available as open source under the terms of the MIT License.