{"id":9239,"date":"2025-07-29T21:35:30","date_gmt":"2025-07-29T16:05:30","guid":{"rendered":"https:\/\/pheonixsolutions.com\/blog\/?p=9239"},"modified":"2025-07-29T21:35:35","modified_gmt":"2025-07-29T16:05:35","slug":"secure-jwt-token-with-graphql-apis","status":"publish","type":"post","link":"https:\/\/pheonixsolutions.com\/blog\/secure-jwt-token-with-graphql-apis\/","title":{"rendered":"Secure JWT token with GraphQL APIs"},"content":{"rendered":"\n<p><strong>Introduction:<\/strong><\/p>\n\n\n\n<p>When creating web applications with GraphQL APIs, securing them is very important. JWT tokens usually handle the security. JWT stands for JSON Web Token. In this post, we\u2019ll explore secure methods for handling tokens, as improper handling or exposure can lead to cross-site attacks.<\/p>\n\n\n\n<p><strong>JWT in Local storage<\/strong>:<\/p>\n\n\n\n<p>A common approach to handling tokens is storing them in local storage and retrieving them when needed. This approach can cause security vulnerabilities, as tokens stored in local storage are easily exposed.<\/p>\n\n\n\n<p>The issues that may occur due to token exposure are:<br><strong>XSS Attacks:<\/strong> Any JavaScript code can access local storage, making tokens vulnerable.<br><strong>Persistent Storage:<\/strong> Tokens remain accessible even after a browser restart.<br><strong>Global Access:<\/strong> Any script on the domain can read the token.<br><em><strong>The Secure Alternative: HTTP-Only cookies<\/strong><br><\/em>The most secure approach is using HTTP-only cookies with the secure and same-site flags.<br>Steps to implement:<br>1. Backend<br>Instead of sending the token in login response body, send it as HTTP-only cookie.<br><em>In index.ts file<\/em><br>const server = new ApolloServer({ <br>typeDefs, <br>resolvers, <br>context: ({ req, res }) => ({ req, res }), <em>\/\/ Pass res to context<\/em><br> });<br><br><em>In Mutation:<\/em><br>loginUser: async ( _: any, { email, password }: { email: string; password: string }, <br>context: any <em>\/\/ Add context parameter<\/em> <br>) => { <br>const { res } = context;<br>Receive the response inside mutation.<br>Generate token:<br>const token = jwt.sign( { <br>userId: user._id, userType: user.user_type }, <br>secrets?.JWT_SECRET as string, { expiresIn: &#8220;8h&#8221; } );<br>Instead of sending token in body response, send it as HTTP cookie.<br>res.cookie(&#8216;authToken&#8217;, token,<br> { httpOnly: true, <br>secure: process.env.NODE_ENV === &#8216;production&#8217;, <br>sameSite: &#8216;strict&#8217;, <br>maxAge: 8 * 60 * 60 * 1000, <em>\/\/ 8 hours<\/em> <br>path: &#8216;\/&#8217;<br> });<br>In Frontend:<br>We have to include credentials: &#8216;include&#8217; in the file, where we have set connection to apollo-client.<br>const httpLink = createHttpLink({ <br>uri: &#8216;end-point&#8217;, <em>\/\/ GraphQL endpoint<\/em> <br>credentials: &#8216;include&#8217;, <em>\/\/  sends cookies with requests<\/em><br> });<br>The extra step we have to do is, while logging out of the application, we need to clear the cookies.<br><strong><em>Alternative approach: In-Memory Storage<\/em><\/strong><br>If we want to control token management, by refresh token method we can use this. Periodically we need to change tokens by adding refresh token method in backend.<br>In frontend, we need to change like the following:<br><em>\/\/ Apollo Client with auth link<\/em> <br>import { setContext } from &#8216;@apollo\/client\/link\/context&#8217;; <br>const authLink = setContext((_, { headers }) => { <br>const token = tokenManager.getToken(); <br>return { <br>headers: { <br>&#8230;headers, <br>authorization: token ? `Bearer ${token}` : &#8220;&#8221;, <br>} }; <br>}); <br>const client = new ApolloClient({ <br>link: authLink.concat(httpLink), <br>cache: new InMemoryCache(),<br> });<\/p>\n\n\n\n<p><strong>Best Practices:<\/strong><br>&#8211; Token expirartion<br>&#8211; CSRF Protection<br>&#8211; Logout Implementation<\/p>\n\n\n\n<p><strong>Conclusion:<\/strong><br>There are several methods available to enhance token security. It&#8217;s important to choose the one that best suits our application&#8217;s requirements. Most of these implementations are straightforward and not overly complex. By adopting the right approach, we can ensure more secure APIs for your application and by the we can earn the trust of application users.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction: When creating web applications with GraphQL APIs, securing them is very important. JWT tokens usually handle the security. JWT stands for JSON Web Token. In this post, we\u2019ll explore secure methods for handling tokens, as improper handling or exposure can lead to cross-site attacks. JWT in Local storage: A&hellip; <a href=\"https:\/\/pheonixsolutions.com\/blog\/secure-jwt-token-with-graphql-apis\/\" class=\"more-link read-more\" rel=\"bookmark\">Continue Reading <span class=\"screen-reader-text\">Secure JWT token with GraphQL APIs<\/span><i class=\"fa fa-arrow-right\"><\/i><\/a><\/p>\n","protected":false},"author":502,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[1],"tags":[],"class_list":{"0":"post-9239","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"hentry","6":"category-uncategorized","7":"h-entry","9":"h-as-article"},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Pheonix Solutions - We Empower Your Business Growth<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/pheonixsolutions.com\/blog\/secure-jwt-token-with-graphql-apis\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Pheonix Solutions - We Empower Your Business Growth\" \/>\n<meta property=\"og:description\" content=\"Introduction: When creating web applications with GraphQL APIs, securing them is very important. JWT tokens usually handle the security. JWT stands for JSON Web Token. In this post, we\u2019ll explore secure methods for handling tokens, as improper handling or exposure can lead to cross-site attacks. JWT in Local storage: A&hellip; Continue Reading Secure JWT token with GraphQL APIs\" \/>\n<meta property=\"og:url\" content=\"https:\/\/pheonixsolutions.com\/blog\/secure-jwt-token-with-graphql-apis\/\" \/>\n<meta property=\"og:site_name\" content=\"PHEONIXSOLUTIONS\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/PheonixSolutions-209942982759387\/\" \/>\n<meta property=\"article:published_time\" content=\"2025-07-29T16:05:30+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-07-29T16:05:35+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/pheonixsolutions.com\/blog\/wp-content\/uploads\/2016\/09\/PX2.png\" \/>\n\t<meta property=\"og:image:width\" content=\"3837\" \/>\n\t<meta property=\"og:image:height\" content=\"2540\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Keerthana P\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@pheonixsolution\" \/>\n<meta name=\"twitter:site\" content=\"@pheonixsolution\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Keerthana P\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/secure-jwt-token-with-graphql-apis\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/secure-jwt-token-with-graphql-apis\\\/\"},\"author\":{\"name\":\"Keerthana P\",\"@id\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/bfb764836e66c01d0c03dd2e79ce94fa\"},\"headline\":\"Secure JWT token with GraphQL APIs\",\"datePublished\":\"2025-07-29T16:05:30+00:00\",\"dateModified\":\"2025-07-29T16:05:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/secure-jwt-token-with-graphql-apis\\\/\"},\"wordCount\":457,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/#organization\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/secure-jwt-token-with-graphql-apis\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/secure-jwt-token-with-graphql-apis\\\/\",\"url\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/secure-jwt-token-with-graphql-apis\\\/\",\"name\":\"Pheonix Solutions - We Empower Your Business Growth\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/#website\"},\"datePublished\":\"2025-07-29T16:05:30+00:00\",\"dateModified\":\"2025-07-29T16:05:35+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/secure-jwt-token-with-graphql-apis\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/secure-jwt-token-with-graphql-apis\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/secure-jwt-token-with-graphql-apis\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Secure JWT token with GraphQL APIs\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/\",\"name\":\"Pheonix Solutions\",\"description\":\"We Empower Your Business Growth\",\"publisher\":{\"@id\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/#organization\",\"name\":\"PheonixSolutions\",\"url\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/12\\\/logo.png\",\"contentUrl\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/12\\\/logo.png\",\"width\":454,\"height\":300,\"caption\":\"PheonixSolutions\"},\"image\":{\"@id\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/PheonixSolutions-209942982759387\\\/\",\"https:\\\/\\\/x.com\\\/pheonixsolution\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/bfb764836e66c01d0c03dd2e79ce94fa\",\"name\":\"Keerthana P\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a2fbfc942637609ceefb9cbdeedd3fe92320c9f5212098280c846d6d8597088c?s=96&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a2fbfc942637609ceefb9cbdeedd3fe92320c9f5212098280c846d6d8597088c?s=96&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a2fbfc942637609ceefb9cbdeedd3fe92320c9f5212098280c846d6d8597088c?s=96&r=g\",\"caption\":\"Keerthana P\"},\"url\":\"https:\\\/\\\/pheonixsolutions.com\\\/blog\\\/author\\\/keerthana\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Pheonix Solutions - We Empower Your Business Growth","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/pheonixsolutions.com\/blog\/secure-jwt-token-with-graphql-apis\/","og_locale":"en_US","og_type":"article","og_title":"Pheonix Solutions - We Empower Your Business Growth","og_description":"Introduction: When creating web applications with GraphQL APIs, securing them is very important. JWT tokens usually handle the security. JWT stands for JSON Web Token. In this post, we\u2019ll explore secure methods for handling tokens, as improper handling or exposure can lead to cross-site attacks. JWT in Local storage: A&hellip; Continue Reading Secure JWT token with GraphQL APIs","og_url":"https:\/\/pheonixsolutions.com\/blog\/secure-jwt-token-with-graphql-apis\/","og_site_name":"PHEONIXSOLUTIONS","article_publisher":"https:\/\/www.facebook.com\/PheonixSolutions-209942982759387\/","article_published_time":"2025-07-29T16:05:30+00:00","article_modified_time":"2025-07-29T16:05:35+00:00","og_image":[{"width":3837,"height":2540,"url":"https:\/\/pheonixsolutions.com\/blog\/wp-content\/uploads\/2016\/09\/PX2.png","type":"image\/png"}],"author":"Keerthana P","twitter_card":"summary_large_image","twitter_creator":"@pheonixsolution","twitter_site":"@pheonixsolution","twitter_misc":{"Written by":"Keerthana P","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/pheonixsolutions.com\/blog\/secure-jwt-token-with-graphql-apis\/#article","isPartOf":{"@id":"https:\/\/pheonixsolutions.com\/blog\/secure-jwt-token-with-graphql-apis\/"},"author":{"name":"Keerthana P","@id":"https:\/\/pheonixsolutions.com\/blog\/#\/schema\/person\/bfb764836e66c01d0c03dd2e79ce94fa"},"headline":"Secure JWT token with GraphQL APIs","datePublished":"2025-07-29T16:05:30+00:00","dateModified":"2025-07-29T16:05:35+00:00","mainEntityOfPage":{"@id":"https:\/\/pheonixsolutions.com\/blog\/secure-jwt-token-with-graphql-apis\/"},"wordCount":457,"commentCount":0,"publisher":{"@id":"https:\/\/pheonixsolutions.com\/blog\/#organization"},"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/pheonixsolutions.com\/blog\/secure-jwt-token-with-graphql-apis\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/pheonixsolutions.com\/blog\/secure-jwt-token-with-graphql-apis\/","url":"https:\/\/pheonixsolutions.com\/blog\/secure-jwt-token-with-graphql-apis\/","name":"Pheonix Solutions - We Empower Your Business Growth","isPartOf":{"@id":"https:\/\/pheonixsolutions.com\/blog\/#website"},"datePublished":"2025-07-29T16:05:30+00:00","dateModified":"2025-07-29T16:05:35+00:00","breadcrumb":{"@id":"https:\/\/pheonixsolutions.com\/blog\/secure-jwt-token-with-graphql-apis\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/pheonixsolutions.com\/blog\/secure-jwt-token-with-graphql-apis\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/pheonixsolutions.com\/blog\/secure-jwt-token-with-graphql-apis\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/pheonixsolutions.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Secure JWT token with GraphQL APIs"}]},{"@type":"WebSite","@id":"https:\/\/pheonixsolutions.com\/blog\/#website","url":"https:\/\/pheonixsolutions.com\/blog\/","name":"Pheonix Solutions","description":"We Empower Your Business Growth","publisher":{"@id":"https:\/\/pheonixsolutions.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/pheonixsolutions.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/pheonixsolutions.com\/blog\/#organization","name":"PheonixSolutions","url":"https:\/\/pheonixsolutions.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/pheonixsolutions.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/pheonixsolutions.com\/blog\/wp-content\/uploads\/2016\/12\/logo.png","contentUrl":"https:\/\/pheonixsolutions.com\/blog\/wp-content\/uploads\/2016\/12\/logo.png","width":454,"height":300,"caption":"PheonixSolutions"},"image":{"@id":"https:\/\/pheonixsolutions.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/PheonixSolutions-209942982759387\/","https:\/\/x.com\/pheonixsolution"]},{"@type":"Person","@id":"https:\/\/pheonixsolutions.com\/blog\/#\/schema\/person\/bfb764836e66c01d0c03dd2e79ce94fa","name":"Keerthana P","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/a2fbfc942637609ceefb9cbdeedd3fe92320c9f5212098280c846d6d8597088c?s=96&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/a2fbfc942637609ceefb9cbdeedd3fe92320c9f5212098280c846d6d8597088c?s=96&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a2fbfc942637609ceefb9cbdeedd3fe92320c9f5212098280c846d6d8597088c?s=96&r=g","caption":"Keerthana P"},"url":"https:\/\/pheonixsolutions.com\/blog\/author\/keerthana\/"}]}},"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p7F4uM-2p1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/9239","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/users\/502"}],"replies":[{"embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=9239"}],"version-history":[{"count":0,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/9239\/revisions"}],"wp:attachment":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=9239"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=9239"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=9239"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}