{
    "componentChunkName": "component---src-pages-blog-markdown-remark-fields-slug-js",
    "path": "/blog/introducing-user-roles-authorization-with-supertokens",
    "result": {"data":{"markdownRemark":{"html":"<h3 id=\"table-of-contents\" style=\"position:relative;\"><a href=\"#table-of-contents\" aria-label=\"table of contents permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Table of Contents</h3>\n<ul>\n<li><a href=\"#part-1---introducing-user-roles-and-understanding-why-authorization-matters\">Part 1 - Introducing user roles and understanding why authorization matters</a>\n<ul>\n<li><a href=\"#introduction\">Introduction</a></li>\n<li><a href=\"#what-are-user-roles-and-why-are-they-important-for-user-authentication\">What are user roles and why are they important for user authentication?</a></li>\n<li><a href=\"#user-roles-and-supertokens\">User Roles and SuperTokens</a></li>\n</ul>\n</li>\n<li><a href=\"#part-2---implement-supertokens-user-roles\">Part 2 - Implement SuperTokens User Roles</a>\n<ul>\n<li><a href=\"#enabling-user-roles-with-supertokens\">Enabling user roles with SuperTokens</a></li>\n<li><a href=\"#step-1-creating-the-roles-and-permissions\">Step 1) Creating the roles and permissions</a></li>\n<li><a href=\"#step-2-assigning-roles-to-users-on-sign-up\">Step 2) Assigning roles to users on sign up</a></li>\n<li><a href=\"#step-3-guarding-apis-based-on-a-users-role-or-permissions\">Step 3) Guarding APIs based on a user’s role or permissions</a></li>\n</ul>\n</li>\n<li><a href=\"#conclusion\">Conclusion</a></li>\n</ul>\n<h2 id=\"part-1---introducing-user-roles-and-understanding-why-authorization-matters\" style=\"position:relative;\"><a href=\"#part-1---introducing-user-roles-and-understanding-why-authorization-matters\" aria-label=\"part 1   introducing user roles and understanding why authorization matters permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Part 1 - Introducing user roles and understanding why authorization matters</h2>\n<h3 id=\"introduction\" style=\"position:relative;\"><a href=\"#introduction\" aria-label=\"introduction permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Introduction</h3>\n<p>Today, we’re excited to announce the launch of user roles within SuperTokens! With user roles, you can now easily attach different sets of permissions to each user.</p>\n<p>At SuperTokens, we’ve put a lot of thought into authentication and authorization.</p>\n<p>Authentication is about: “Which user is this request coming from?”</p>\n<p>Authorization is about: “Is this user allowed to do a certain operation?”</p>\n<p>In the past, we’ve focused on authentication with our <a href=\"https://supertokens.com/docs/emailpassword/introduction\" target=\"_blank\" rel=\"nofollow\">email password</a>, <a href=\"https://supertokens.com/docs/passwordless/introduction\" target=\"_blank\" rel=\"nofollow\">password-less</a>, <a href=\"https://supertokens.com/docs/thirdparty/introduction\" target=\"_blank\" rel=\"nofollow\">social</a>, and <a href=\"https://supertokens.com/docs/phonepassword/introduction\" target=\"_blank\" rel=\"nofollow\">phone</a> authentication recipes.</p>\n<p>User roles address the authorization side of the puzzle. Continuing on our momentum with our authentication product, we’re excited to help you manage your users with finer controls without compromising on application security.</p>\n<p>If you’re looking to implement user roles today, check out the <a href=\"#part-2---implement-supertokens-user-roles\">second part of this post</a> or our <a href=\"https://supertokens.com/docs/userroles/introduction\" target=\"_blank\" rel=\"nofollow\">user roles documentation</a>.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/b451024e895adf327ad54e7e09cec163/b9024/authn-to-authz.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 51.26582278481012%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB1UlEQVQoz1WSy3LUMBBFZ5f4KbX8tuXH2J5nJkAWqUpBsUixoFiw5wP4/184YHkmgcUttVrS1e3uu9FaEK0R0W5VC5QmuiFe4c6vd9wb0f/jmt+4QASlDVoMeSqUmfBhSHgcUoY6YWxSlBaUGERWstubG5b9wrVZA0WmPIbMZ5t5tGlAVxq2lbArQ16mmJdZoSMPI6uSVIcU2qMQn1x7iI4d6WYpcZvdc2yF0alJOFQhokJy7TNXMbNN+TTl7GuFTXwSHXKqA2abMFSGgzWMuYd2CrViLgKsbfjxPPDx0DPUKbUJ6FKPuas4zx3zYBm72lVRic+2TjhOHd+eevrOMpehU7lZyh1zn6au+P3a8fXR0hSGygQ0xuM0FPz60vHz2XIZS6ewFJ++FM6T5ftTw9TXDHnwTriU3LWWh/OJad65MkoJaOSOw9hxPJ3ZH47sxp42Wfu2LTW2Hxl3BxrbOlEL12ZpcG08pnzpl2IqI7bpPYmOySRkKnz2jeLcKhcXEmBE0SV3XNqY14fUtcEab7XNMpklMDrGqAijI/fTklsdEJPoiC4LGYqYqTYc24RLb/i8N5xbIY4jZyc35Zup9TVxw82wb7m3D7Sb5upDIVb/3P875T8Lc/vCMX2OeQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"AuthN to AuthZ\"\n        title=\"AuthN to AuthZ\"\n        src=\"/static/b451024e895adf327ad54e7e09cec163/f058b/authn-to-authz.png\"\n        srcset=\"/static/b451024e895adf327ad54e7e09cec163/c26ae/authn-to-authz.png 158w,\n/static/b451024e895adf327ad54e7e09cec163/6bdcf/authn-to-authz.png 315w,\n/static/b451024e895adf327ad54e7e09cec163/f058b/authn-to-authz.png 630w,\n/static/b451024e895adf327ad54e7e09cec163/40601/authn-to-authz.png 945w,\n/static/b451024e895adf327ad54e7e09cec163/b9024/authn-to-authz.png 1203w\"\n        sizes=\"(max-width: 630px) 100vw, 630px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<h3 id=\"what-are-user-roles-and-why-are-they-important-for-user-authentication\" style=\"position:relative;\"><a href=\"#what-are-user-roles-and-why-are-they-important-for-user-authentication\" aria-label=\"what are user roles and why are they important for user authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What are user roles and why are they important for user authentication?</h3>\n<p>User Roles is built based on principles of roles-based access control (RBAC).</p>\n<p>RBAC is a security model that restricts access to resources based on the roles that users have within an organization. Users are assigned to specific roles and those roles are granted permissions to access certain resources.</p>\n<p>Let’s try building a blogging app with user roles.  </p>\n<p>We’d want to have a <code class=\"language-text\">regular-users</code> role that allows regular users to read all blog posts, but only edit or delete posts created by themselves. We’d also want to have an <code class=\"language-text\">admin</code> role where admins can create, edit, and delete all blog posts.</p>\n<p>In formal notation, the actions that can be taken can be represented as strings like:</p>\n<ul>\n<li>Read all blogs: <code class=\"language-text\">read:all</code></li>\n<li>Delete all blogs: <code class=\"language-text\">delete:all</code></li>\n<li>Delete blogs created by self: <code class=\"language-text\">delete:self</code></li>\n<li>Edit all blogs: <code class=\"language-text\">edit:all</code></li>\n<li>Edit blogs created by self: <code class=\"language-text\">edit:self</code></li>\n</ul>\n<p>These are known as permissions. In a grid form, the roles and permissions for our example app will look like this:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/c75873293d8f73846e5e9bc6851bf8be/f058b/permission_grid.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 45.56962025316456%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAAsTAAALEwEAmpwYAAABZ0lEQVQoz1WR246jMAyGuW+ADiSOTzkQAqVMO53d93+4VTorrday5N+f9dsX7qbrWGnYqd+4v8m487Bhv/G4Yl+8qTQsYDKYBYfoLgn6BEOwF7Vmuo5dBrOHKaeYlBHmuqTP+y0FPvb1PLYc9Tz2+21LQY69rktKQc77cSsq86Ur3kSaU6khxGmeS6lfX9+i4Tw/n89XSvnr9f14PmNMj8ez1i3E+Pr1e69F50u3eFPUTdPk7OzBE6FHEBFE7xGY2XsP8BYIxMjM1jllH5xplzPbV/VnBmshJqp3JJRcqNyQSbSFMMl6YFyYuZGk1MwZTCJ7nd1sHYAXkTYXUW1SVZnlDX7aVtBzlLc5ObMFt0WoAQi9BM4r/Ri4LdK4cMzEJH8hc1opBgrWdMFeHnl+rXBmpwQx0rp5ZVbhoM29FMwFhVsbtPGyYYlerensx7h4835gn32/4JBhyP5fJhgyjP+TMUNvr+Mf2nQ5H8NGaGkAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Permission Grid\"\n        title=\"Permission Grid\"\n        src=\"/static/c75873293d8f73846e5e9bc6851bf8be/f058b/permission_grid.png\"\n        srcset=\"/static/c75873293d8f73846e5e9bc6851bf8be/c26ae/permission_grid.png 158w,\n/static/c75873293d8f73846e5e9bc6851bf8be/6bdcf/permission_grid.png 315w,\n/static/c75873293d8f73846e5e9bc6851bf8be/f058b/permission_grid.png 630w\"\n        sizes=\"(max-width: 630px) 100vw, 630px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>The <code class=\"language-text\">edit:all</code> permission implies <code class=\"language-text\">edit:self</code> as well. Same goes for the <code class=\"language-text\">delete</code> permission.</p>\n<p>To learn more about RBAC, check out our <a href=\"http://supertokens.com/blog/what-is-roles-based-access-control-vs-abac\" target=\"_blank\" rel=\"nofollow\">blog post going in depth on RBAC</a>.</p>\n<h3 id=\"user-roles-and-supertokens\" style=\"position:relative;\"><a href=\"#user-roles-and-supertokens\" aria-label=\"user roles and supertokens permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>User Roles and SuperTokens</h3>\n<p>We built user roles with simplicity in mind. Our goal was to build secure authorization that can be set up in the span of minutes, not hours. As a result, our default user roles product is perfect for most non-complex use cases. For power users, we’ve left plenty of room to work with a product such as <a href=\"http://permit.io/\" target=\"_blank\" rel=\"nofollow\">permit.io</a> to extend our core permission feature set.</p>\n<p>Today, you can create new roles and permissions, assign them to users, and protect API and website routes with SuperTokens. Let’s go over each one at a high level.</p>\n<ul>\n<li>Create new roles and permissions - With SuperTokens, roles and permissions are simple strings that can be assigned to users. That means you can name your role anything from <code class=\"language-text\">user</code> to <code class=\"language-text\">super-admin-i-have-all-the-permissions</code>.</li>\n<li>Assign roles to users - Once you’ve created the role, you can assign roles to users after sign up. In fact, you can even assign multiple roles to a single user, so you could give someone both <code class=\"language-text\">regular-user</code> and <code class=\"language-text\">admin</code> permissions.</li>\n<li>Product API and website routes - Now to verify if a user has proper permissions, we need to verify that a session exists and validate that the roles/permissions saved in the access token payload have the appropriate values. Fetching the user’s role from their session is simple, and since our roles are strings, verification is as simple as a string comparison.</li>\n</ul>\n<h2 id=\"part-2---implement-supertokens-user-roles\" style=\"position:relative;\"><a href=\"#part-2---implement-supertokens-user-roles\" aria-label=\"part 2   implement supertokens user roles permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Part 2 - Implement SuperTokens User Roles</h2>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/667a453cb9cb9af45e3562153bd3b109/b9024/authorization-functions.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 51.26582278481012%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAACoUlEQVQozxXQ61NSaQCAcf6KnS0z0+A9weF+O3KVm9wOEEhIgK2Foik6ObPWOpvCtOMKW4EQ4O7+s8/b8OH5+vvwGFbf3/Kse8fzi2+Iy3ssV3NsVwscH2e4fp/juZjhPf+BvztDO1kQPF4Q7iyItuds7c+J781JNmakahPS1QmGx60eT99+Ya10yHqsiCleQD24xvnpAdvlPa6LKb7zBb7237gyTWxbNayRKvZwFeey4Ev88Tap6phMZYLh190bVpt9ViI7iHBcCrdPKtX3OD/+hzj6C3t3xOaH/3E3P2MObEtFS0nh2ZKKIygV1S8Vi0vaPGkSpSHZ8gTDL9UeK7s9Hif2UNM7GANJKSonOM6maFcLtIs5WvcBT/1PjJEiplQNJVlFCWRRrCEUVZMOr06yOCT3cglWejyq9litfGKtcM66fobSuMbeGWI9vcZzPiB49i+e+meMvrQ0+jKYPNsId1IKWwRh2ZR2t05KH5AvLcFyj0c7fZ7muqzH6hhjdUT5EvPeLe7TO/yn3wl1F3hfX2PypRHelBTuJIozLoU1irAEpd1dYDs/QC8sH1Z6PHnVZyVY5pkjITcsPmlKvEFtDPB37gkczwifPLDZ6mOJllDDRdSgzgtvEqHGEJawtLuKbOcGFPQJhpVXN6zt9ngSayIidTbcKWlMvcPWHOI5/MpmZ0Lk6AF/7Qbhy0vhzcoX3py0eNLSZI5KkzkkbQ6ddOaOYn6CYa1+w/qy4geMmQOMqX3MO3/g+O0fgsczQkczQgc/CDTusMXaWENvcETe4o13cGotXL4GWqBDLvuVUvYew0arz/NmH9H8gtK6Rd0f4mx/w3s4RjucEDyYEn43Jbo/Zas1IfZ6TKI2Iln5Tro8IlMckddHFHJjSukxPwGW1IB0QluAbQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Authorization Functions\"\n        title=\"Authorization Functions\"\n        src=\"/static/667a453cb9cb9af45e3562153bd3b109/f058b/authorization-functions.png\"\n        srcset=\"/static/667a453cb9cb9af45e3562153bd3b109/c26ae/authorization-functions.png 158w,\n/static/667a453cb9cb9af45e3562153bd3b109/6bdcf/authorization-functions.png 315w,\n/static/667a453cb9cb9af45e3562153bd3b109/f058b/authorization-functions.png 630w,\n/static/667a453cb9cb9af45e3562153bd3b109/40601/authorization-functions.png 945w,\n/static/667a453cb9cb9af45e3562153bd3b109/b9024/authorization-functions.png 1203w\"\n        sizes=\"(max-width: 630px) 100vw, 630px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<h3 id=\"enabling-user-roles-with-supertokens\" style=\"position:relative;\"><a href=\"#enabling-user-roles-with-supertokens\" aria-label=\"enabling user roles with supertokens permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Enabling user roles with SuperTokens</h3>\n<p>We’ve built user roles based on the principles of <a href=\"https://supertokens.com/blog/what-is-roles-based-access-control-vs-abac\" target=\"_blank\" rel=\"nofollow\">RBAC</a>.</p>\n<p>Let’s use our previous example again. A quick reminder -</p>\n<ul>\n<li>we have a <code class=\"language-text\">regular-user</code> role which will allow users to read all blog posts, but only edit or delete posts created by them.</li>\n<li>we also also have an <code class=\"language-text\">admin</code> role which allows admins to create, edit, and delete any blog posts.</li>\n</ul>\n<blockquote>\n<p>The code snippets below are for a NodeJS backend, but similar logic applies for the other backend SDKs offered by SuperTokens as well. </p>\n</blockquote>\n<h3 id=\"step-1-creating-the-roles-and-permissions\" style=\"position:relative;\"><a href=\"#step-1-creating-the-roles-and-permissions\" aria-label=\"step 1 creating the roles and permissions permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 1) Creating the roles and permissions</h3>\n<p>To start, SuperTokens needs to know about the roles and permissions before they can be assigned to users. For that, we can use the <code class=\"language-text\">UserRoles.createNewRoleOrAddPermissions</code> function exposed by the SDK:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"46506062495761500000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied!\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`import UserRoles from &quot;supertokens-node/recipe/userroles&quot;;\n\n// creating the admin role and adding permissions to it.\nawait UserRoles.createNewRoleOrAddPermissions(&quot;admin&quot;, [&quot;read:all&quot;, &quot;delete:all&quot;, &quot;edit:all&quot;])\n\n// creating the regular-user role and adding permissions to it.\nawait UserRoles.createNewRoleOrAddPermissions(&quot;regular-user&quot;, [&quot;read:all&quot;, &quot;delete:self&quot;, &quot;edit:self&quot;])`, `46506062495761500000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"ts\"><pre class=\"language-ts\"><code class=\"language-ts\"><span class=\"token keyword\">import</span> UserRoles <span class=\"token keyword\">from</span> <span class=\"token string\">\"supertokens-node/recipe/userroles\"</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">// creating the admin role and adding permissions to it.</span>\n<span class=\"token keyword\">await</span> UserRoles<span class=\"token punctuation\">.</span><span class=\"token function\">createNewRoleOrAddPermissions</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"admin\"</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token string\">\"read:all\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"delete:all\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"edit:all\"</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\">// creating the regular-user role and adding permissions to it.</span>\n<span class=\"token keyword\">await</span> UserRoles<span class=\"token punctuation\">.</span><span class=\"token function\">createNewRoleOrAddPermissions</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"regular-user\"</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token string\">\"read:all\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"delete:self\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"edit:self\"</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>This allows us to declare both the name of the role as well as the permissions related to the role. Fairly simple stuff.</p>\n<h3 id=\"step-2-assigning-roles-to-users-on-sign-up\" style=\"position:relative;\"><a href=\"#step-2-assigning-roles-to-users-on-sign-up\" aria-label=\"step 2 assigning roles to users on sign up permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 2) Assigning roles to users on sign up</h3>\n<p>With SuperTokens you can:</p>\n<ul>\n<li>Assign roles to users and their sessions</li>\n<li>Remove roles from users and their sessions</li>\n<li>Get a list of all roles assigned to a specific user</li>\n<li>Get a list of all users that are assigned a specific role</li>\n</ul>\n<p>For our example, we’ll simply assign our created roles to users through the <code class=\"language-text\">UserRoles.addRoleToUser</code> function. To do this, we use the following snippet in our override function for the sign up API:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"69406369114426680000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied!\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`import UserRoles from &quot;supertokens-node/recipe/userroles&quot;;\n\n// The value of roleToAssign needs to be fetched by you.\n// For example, you could check if the user's email is of a certain domain,\n// and if it is, then they would be an admin, else not.\nif (roleToAssign === &quot;admin&quot;) {\n    // the userId belongs to the user who just signed up.\n    await UserRoles.addRoleToUser(userId, &quot;admin&quot;);\n} else {\n    await UserRoles.addRoleToUser(userId, &quot;regular-user&quot;);\n}`, `69406369114426680000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"ts\"><pre class=\"language-ts\"><code class=\"language-ts\"><span class=\"token keyword\">import</span> UserRoles <span class=\"token keyword\">from</span> <span class=\"token string\">\"supertokens-node/recipe/userroles\"</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">// The value of roleToAssign needs to be fetched by you.</span>\n<span class=\"token comment\">// For example, you could check if the user's email is of a certain domain,</span>\n<span class=\"token comment\">// and if it is, then they would be an admin, else not.</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>roleToAssign <span class=\"token operator\">===</span> <span class=\"token string\">\"admin\"</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// the userId belongs to the user who just signed up.</span>\n    <span class=\"token keyword\">await</span> UserRoles<span class=\"token punctuation\">.</span><span class=\"token function\">addRoleToUser</span><span class=\"token punctuation\">(</span>userId<span class=\"token punctuation\">,</span> <span class=\"token string\">\"admin\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">await</span> UserRoles<span class=\"token punctuation\">.</span><span class=\"token function\">addRoleToUser</span><span class=\"token punctuation\">(</span>userId<span class=\"token punctuation\">,</span> <span class=\"token string\">\"regular-user\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>We can even manually <a href=\"https://supertokens.com/docs/userroles/managing-roles-and-users\" target=\"_blank\" rel=\"nofollow\">add the roles and permissions to the user’s session payload</a> for efficient access at a later point. SuperTokens does this automatically as long as you have assigned the roles to a user before their session is created.</p>\n<h3 id=\"step-3-guarding-apis-based-on-a-users-role-or-permissions\" style=\"position:relative;\"><a href=\"#step-3-guarding-apis-based-on-a-users-role-or-permissions\" aria-label=\"step 3 guarding apis based on a users role or permissions permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 3) Guarding APIs based on a user’s role or permissions</h3>\n<p>Assigning roles to users is only half the battle.</p>\n<p>We also need to retrieve the roles and permissions to understand if a user is allowed to perform certain functions. We can use the following code snippet to complete session verification (the authentication piece of the puzzle) and then implement our authorization logic:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"88005330037289140000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied!\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`import { verifySession } from &quot;supertokens-node/recipe/session/framework/express&quot;;\nimport UserRoles from &quot;supertokens-node/recipe/userroles&quot;;\n\napp.delete(&quot;/blog&quot;, verifySession(), async (req, res) => {\n    let blogId = req.body.blogId\n    let userId = req.session.getUserId();\n\n    // if the user is an admin, we will get [&quot;admin&quot;], \n    // else we will get [&quot;regular-user&quot;]\n    let roles = req.session.getClaimValue(UserRoles.UserRoleClaim)\n\n    // if the role is &quot;admin&quot;, we get [&quot;read:all&quot;, &quot;delete:all&quot;, &quot;edit:all&quot;]\n    // else we get [&quot;read:all&quot;, &quot;delete:self&quot;, &quot;edit:self&quot;]\n    let permissions = await req.session.getClaimValue(UserRoles.PermissionClaim)\n\n    if (permissions.includes(&quot;delete:all&quot;)) {\n        // allow delete\n    } else if (permissions.includes(&quot;delete:self&quot;)) {\n        if (getOwnerOfBlog(blogId) === userId) {\n            // allow delete\n        } else {\n            // return access denied error\n        }\n    }\n})`, `88005330037289140000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"ts\"><pre class=\"language-ts\"><code class=\"language-ts\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> verifySession <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">\"supertokens-node/recipe/session/framework/express\"</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> UserRoles <span class=\"token keyword\">from</span> <span class=\"token string\">\"supertokens-node/recipe/userroles\"</span><span class=\"token punctuation\">;</span>\n\napp<span class=\"token punctuation\">.</span><span class=\"token function\">delete</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"/blog\"</span><span class=\"token punctuation\">,</span> <span class=\"token function\">verifySession</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span>req<span class=\"token punctuation\">,</span> res<span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">let</span> blogId <span class=\"token operator\">=</span> req<span class=\"token punctuation\">.</span>body<span class=\"token punctuation\">.</span>blogId\n    <span class=\"token keyword\">let</span> userId <span class=\"token operator\">=</span> req<span class=\"token punctuation\">.</span>session<span class=\"token punctuation\">.</span><span class=\"token function\">getUserId</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">// if the user is an admin, we will get [\"admin\"], </span>\n    <span class=\"token comment\">// else we will get [\"regular-user\"]</span>\n    <span class=\"token keyword\">let</span> roles <span class=\"token operator\">=</span> req<span class=\"token punctuation\">.</span>session<span class=\"token punctuation\">.</span><span class=\"token function\">getClaimValue</span><span class=\"token punctuation\">(</span>UserRoles<span class=\"token punctuation\">.</span>UserRoleClaim<span class=\"token punctuation\">)</span>\n\n    <span class=\"token comment\">// if the role is \"admin\", we get [\"read:all\", \"delete:all\", \"edit:all\"]</span>\n    <span class=\"token comment\">// else we get [\"read:all\", \"delete:self\", \"edit:self\"]</span>\n    <span class=\"token keyword\">let</span> permissions <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> req<span class=\"token punctuation\">.</span>session<span class=\"token punctuation\">.</span><span class=\"token function\">getClaimValue</span><span class=\"token punctuation\">(</span>UserRoles<span class=\"token punctuation\">.</span>PermissionClaim<span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>permissions<span class=\"token punctuation\">.</span><span class=\"token function\">includes</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"delete:all\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token comment\">// allow delete</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>permissions<span class=\"token punctuation\">.</span><span class=\"token function\">includes</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"delete:self\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token function\">getOwnerOfBlog</span><span class=\"token punctuation\">(</span>blogId<span class=\"token punctuation\">)</span> <span class=\"token operator\">===</span> userId<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token comment\">// allow delete</span>\n        <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token comment\">// return access denied error</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>To sum this code snippet up -</p>\n<ul>\n<li>we’ve found the user’s role using <code class=\"language-text\">UserRoles.UserRoleClaim</code></li>\n<li>we’ve found the user’s permissions using <code class=\"language-text\">UserRoles.PermissionClaim</code></li>\n<li>we’ve set up permission barriers around the delete function</li>\n</ul>\n<p>And we’re done! We’ve now created new roles + permissions, assigned them to users, and protected our API routes against unauthorized access.</p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>User roles is a major step forward for SuperTokens as a company. By pooling both authentication and authorization, we’re one step closer to making the best user authentication tool on the market. And we couldn’t have done it witout you.</p>\n<p>You can learn more about how to use user roles and permissions with SuperTokens via the <a href=\"https://supertokens.com/docs/userroles/introduction\" target=\"_blank\" rel=\"nofollow\">recipe guides docs!</a></p>","frontmatter":{"date":"October 27, 2022","title":"Introducing User Roles Authorization with SuperTokens","cover":"user_roles_cover.png","author":"Advait Ruia","description":"With user roles, you can now use SuperTokens to easily attach a different set of permissions to each user."},"fields":{"slug":"/introducing-user-roles-authorization-with-supertokens/"}},"site":{"siteMetadata":{"title":"SuperTokens Blog"}}},"pageContext":{"id":"0f8f5fa1-f411-5de4-919b-2f10a558a528","fields__slug":"/introducing-user-roles-authorization-with-supertokens/","__params":{"fields__slug":"introducing-user-roles-authorization-with-supertokens"}}},
    "staticQueryHashes": []}