{"id":16576552,"url":"https://github.com/koole/react-sanctum","last_synced_at":"2025-05-16T05:03:53.790Z","repository":{"id":37552931,"uuid":"244050776","full_name":"koole/react-sanctum","owner":"koole","description":"Easily hook up your React app to Laravel Sanctum and Laravel Fortify","archived":false,"fork":false,"pushed_at":"2025-03-26T13:55:23.000Z","size":5151,"stargazers_count":152,"open_issues_count":29,"forks_count":27,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-05-16T05:02:03.866Z","etag":null,"topics":["authentication","laravel-fortify","laravel-sanctum","react","react-components","sanctum","two-factor-authentication"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/koole.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-02-29T22:29:04.000Z","updated_at":"2025-04-29T12:53:14.000Z","dependencies_parsed_at":"2024-06-19T17:11:56.637Z","dependency_job_id":"db98d19a-062d-4580-aa98-6b2c43527cc2","html_url":"https://github.com/koole/react-sanctum","commit_stats":{"total_commits":236,"total_committers":11,"mean_commits":"21.454545454545453","dds":0.4491525423728814,"last_synced_commit":"3d3a48b7355d7dee92763fd521949e44fb638405"},"previous_names":["koole/react-airlock"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koole%2Freact-sanctum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koole%2Freact-sanctum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koole%2Freact-sanctum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koole%2Freact-sanctum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/koole","download_url":"https://codeload.github.com/koole/react-sanctum/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254471062,"owners_count":22076585,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","laravel-fortify","laravel-sanctum","react","react-components","sanctum","two-factor-authentication"],"created_at":"2024-10-11T22:08:31.014Z","updated_at":"2025-05-16T05:03:53.743Z","avatar_url":"https://github.com/koole.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\u003cimg src=\"art/logo.svg\" alt=\"Logo Laravel Sanctum\"\u003e\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/koole/react-sanctum/actions/workflows/tests.yaml\"\u003e\u003cimg src=\"https://github.com/koole/react-sanctum/actions/workflows/tests.yaml/badge.svg\" alt=\"Build Status\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/react-sanctum\"\u003e\u003cimg alt=\"npm\" src=\"https://img.shields.io/npm/dt/react-sanctum\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/react-sanctum\"\u003e\u003cimg alt=\"npm\" src=\"https://img.shields.io/npm/v/react-sanctum\"\u003e\u003c/a\u003e\n  \u003cimg alt=\"npm bundle size\" src=\"https://img.shields.io/bundlephobia/minzip/react-sanctum\"\u003e\n  \u003cimg alt=\"GitHub\" src=\"https://img.shields.io/github/license/koole/react-sanctum\"\u003e\n\u003c/p\u003e\n\n## Introduction\n\nReact Sanctum package provides an easy way to authenticate your React application with [Laravel Sanctum](https://laravel.com/docs/8.x/sanctum#introduction).\n\n- Easily hook up your React app to Laravel Sanctum\n- Works with both hooks and class components\n- Built in support for two factor authentication with [Laravel Fortify](https://laravel.com/docs/8.x/fortify#introduction)\n- Just one dependency: [axios](https://github.com/axios/axios)\n\n## Usage\n\nInstall from NPM\n\n```\nnpm i react-sanctum\n```\n\nWrap your application in a `\u003cSanctum\u003e` component\n\n### Example\n\n```js\nimport React from \"react\";\n\nimport { Sanctum } from \"react-sanctum\";\n\nconst sanctumConfig = {\n  apiUrl: \"http://foobar.test\",\n  csrfCookieRoute: \"sanctum/csrf-cookie\",\n  signInRoute: \"login\",\n  signOutRoute: \"logout\",\n  userObjectRoute: \"user\",\n};\n\nconst App = () =\u003e (\n  \u003cdiv className=\"my-application\"\u003e\n    \u003cSanctum config={sanctumConfig}\u003e/* Your application code */\u003c/Sanctum\u003e\n  \u003c/div\u003e\n);\n```\n\nYou can then use the `useSanctum()` hook to get authentication status, user data and sanctum related\nmethods in any component.\n\n```js\nimport React from \"react\";\nimport { useSanctum } from \"react-sanctum\";\n\nconst LoginButton = () =\u003e {\n  const { authenticated, user, signIn } = useSanctum();\n\n  const handleLogin = () =\u003e {\n    const email = \"sanctum@example.org\";\n    const password = \"example\";\n    const remember = true;\n\n    signIn(email, password, remember)\n      .then(() =\u003e window.alert(\"Signed in!\"))\n      .catch(() =\u003e window.alert(\"Incorrect email or password\"));\n  };\n\n  if (authenticated === true) {\n    return \u003ch1\u003eWelcome, {user.name}\u003c/h1\u003e;\n  } else {\n    return \u003cbutton onClick={handleLogin}\u003eSign in\u003c/button\u003e;\n  }\n};\n\nexport default LoginButton;\n```\n\nOr use the `withSanctum()` higher-order component to get these same values.\n\n```js\nimport React from \"react\";\nimport { withSanctum } from \"react-sanctum\";\n\nconst LoginButton = ({ authenticated, user, signIn }) =\u003e {\n    ...\n};\n\nexport default withSanctum(LoginButton);\n```\n\nYou can also directly consume the Sanctum context by importing `SanctumContext`.\n\nThe `useSanctum` hook and the `withSanctum` HOC give you access to the `SanctumContext`, which contains the following\ndata and methods:\n| | Description |\n|-|------------------------------------------------------------------------------------|\n| `user` | Object your API returns with user data |\n| `authenticated` | Boolean, or null if authentication has not yet been checked |\n| `signIn()` | Accepts `(email, password, remember?)`, returns a promise, resolves with `{twoFactor: boolean, signedIn: boolean, user: {}}`. |\n| `signOut()` | Returns a promise |\n| `setUser()` | Accepts `(user, authenticated?)`, allows you to manually set the user object and optionally its authentication status (boolean). |\n| `twoFactorChallenge()` | Accepts `(code, recovery?)`, returns a promise, resolves with the user object. |\n| `checkAuthentication()` | Returns the authentication status. If it's null, it will ask the server and update `authenticated`. |\n\n# Setup\n\nAll URLS in the config are required. These need to be created in your Laravel app.\n\n```js\nconst sanctumConfig = {\n  // Your application URL\n  apiUrl: \"http://foobar.test\",\n  // The following settings are URLS that need to be created in your Laravel application\n  // The URL sanctum uses for the csrf cookie\n  csrfCookieRoute: \"sanctum/csrf-cookie\",\n  // {email: string, password: string, remember: true | null} get POSTed to here\n  signInRoute: \"api/login\",\n  // A POST request is sent to this route to sign the user out\n  signOutRoute: \"api/logout\",\n  // Used (GET) for checking if the user is signed in (so this should be protected)\n  // The returned object will be avaiable as `user` in the React components.\n  userObjectRoute: \"api/user\",\n  // The URL where the OTAP token or recovery code will be sent to (optional).\n  // Only needed if you want to use two factor authentication.\n  twoFactorChallengeRoute: \"two-factor-challenge\",\n  // An axios instance to be used by react-sanctum (optional). Useful if you for example need to add custom interceptors.\n  axiosInstance: AxiosInstance,\n  // Optional key used for the username POSTed to Laravel, defaults to \"email\". \n  usernameKey: \"email\";\n};\n```\n\nreact-sanctum automatically checks if the user is signed in when the the `\u003cSanctum\u003e`\ncomponent gets mounted. If you don't want this, and want to manually use the\n`checkAuthentication` function later, set `checkOnInit` to `false` like so:\n\n```js\n\u003cSanctum config={sanctumConfig} checkOnInit={false}\u003e\n```\n\n# Handling registration\n\nMethods for signIn and signOut are provided by this library. Registration is not included as there seem to be many ways\npeople handle registration flows.\n\nIf you want to sign in your user after registration, there's an easy way to do this. First, make sure the endpoint you\npost the registration data to signs in the user (`Auth::guard()-\u003elogin(...)`) and have it return the user object to the\nfront-end.\n\nIn your front-end you can then pass this user object into the `setUser()` function, et voilà, your new user has been\nsigned in.\n\nFor example:\n\n```js\naxios\n    .post(`${API_URL}/register`, data)\n    .then(function (response) {\n        const user = response.data;\n        setUser(user); // The react-sanctum setUser function\n        ...\n    })\n    .catch(function (error) {\n        ...\n    });\n```\n\n# Two factor authentication\n\nThis package supports two factor authentication using Laravel Fortify out of the box.\n\n1.  Install Laravel Fortify using the following instructions\n    https://laravel.com/docs/8.x/fortify#installation\n\n2.  Add the `TwoFactorAuthenticable` trait to the User model\n    https://laravel.com/docs/8.x/fortify#two-factor-authentication\n\n3.  Make sure the `two-factor-challenge` route is included in the `config/cors.php` file.\n\nExample for implementation:\n\n```js\nimport React, { useState } from \"react\";\nimport { useSanctum } from \"react-sanctum\";\n\nconst Login = () =\u003e {\n  const [showTwoFactorForm, setShowTwoFactorForm] = useState(false);\n  const [code, setCode] = useState(\"\");\n  const [recoveryCode, setRecoveryCode] = useState(\"\");\n  const { authenticated, user, signIn, twoFactorChallenge } = useSanctum();\n\n  const handleLogin = () =\u003e {\n    const email = \"sanctum@example.org\";\n    const password = \"password\";\n    const remember = true;\n\n    signIn(email, password, remember)\n      .then(({ twoFactor }) =\u003e {\n        if (twoFactor) {\n          setShowTwoFactorForm(true);\n          return;\n        }\n\n        window.alert(\"Signed in without token!\");\n      })\n      .catch(() =\u003e window.alert(\"Incorrect email or password\"));\n  };\n\n  const handleTwoFactorChallenge = (recovery = false) =\u003e {\n    twoFactorChallenge(recovery ? recoveryCode : code, recovery)\n      .then(() =\u003e window.alert(\"Signed in with token!\"))\n      .catch(() =\u003e window.alert(\"Incorrect token\"));\n  };\n\n  if (authenticated === true) {\n    return \u003ch1\u003eWelcome, {user.name}\u003c/h1\u003e;\n  } else {\n    if (showTwoFactorForm) {\n      return (\n        \u003cdiv\u003e\n          \u003cinput\n            type=\"text\"\n            onInput={(event) =\u003e setCode(event.currentTarget.value)}\n          /\u003e\n          \u003cbutton onClick={() =\u003e handleTwoFactorChallenge()}\u003e\n            Sign in using OTAP-token\n          \u003c/button\u003e\n          \u003chr /\u003e\n          \u003cinput\n            type=\"text\"\n            onInput={(event) =\u003e setRecoveryCode(event.currentTarget.value)}\n          /\u003e\n          \u003cbutton onClick={() =\u003e handleTwoFactorChallenge(true)}\u003e\n            Sign in using recovery token\n          \u003c/button\u003e\n        \u003c/div\u003e\n      );\n    }\n\n    return \u003cbutton onClick={handleLogin}\u003eSign in\u003c/button\u003e;\n  }\n};\n\nexport default Login;\n```\n\n# Axios\n\nQuick tip for people using axios: react-sanctum uses Axios for making requests to your server. If your project is also\nusing axios, make sure to set\n`axios.defaults.withCredentials = true;`. That way axios will authenticate your requests to the server properly.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkoole%2Freact-sanctum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkoole%2Freact-sanctum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkoole%2Freact-sanctum/lists"}