{"action":"created","issue":{"url":"https://api.github.com/repos/hapijs/crumb/issues/54","labels_url":"https://api.github.com/repos/hapijs/crumb/issues/54/labels{/name}","comments_url":"https://api.github.com/repos/hapijs/crumb/issues/54/comments","events_url":"https://api.github.com/repos/hapijs/crumb/issues/54/events","html_url":"https://github.com/hapijs/crumb/issues/54","id":94764476,"number":54,"title":"Getting 403 forbidden because token has changed","user":{"login":"marlonmantilla","id":238278,"avatar_url":"https://avatars.githubusercontent.com/u/238278?v=3","gravatar_id":"","url":"https://api.github.com/users/marlonmantilla","html_url":"https://github.com/marlonmantilla","followers_url":"https://api.github.com/users/marlonmantilla/followers","following_url":"https://api.github.com/users/marlonmantilla/following{/other_user}","gists_url":"https://api.github.com/users/marlonmantilla/gists{/gist_id}","starred_url":"https://api.github.com/users/marlonmantilla/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/marlonmantilla/subscriptions","organizations_url":"https://api.github.com/users/marlonmantilla/orgs","repos_url":"https://api.github.com/users/marlonmantilla/repos","events_url":"https://api.github.com/users/marlonmantilla/events{/privacy}","received_events_url":"https://api.github.com/users/marlonmantilla/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-07-13T16:50:20Z","updated_at":"2015-07-14T15:18:24Z","closed_at":null,"body":"Hi guys, I'm working in a HapiJS API and a separate Web client app (Just HTML and JS) which basically will have a form with a CSRF crumb token.  So the Web app basically makes a call to GET /generate and HapiJS will return the CSRF token. After that when I submit the form I hit POST /send and sends the token with X-CSRF-Token header but for some reason is returning 403 ... \r\n\r\nHAPIJS Routes\r\n\r\n```javascript\r\nserver.route([\r\n        {\r\n            method: 'GET',\r\n            path: '/generate',\r\n            handler: Controllers.Auth.generate_csrf,\r\n            config: {\r\n                auth: false,\r\n                jsonp: 'callback'\r\n            }\r\n        },\r\n        // request header \"X-CSRF-Token\" with crumb value must be set in request for this route\r\n        {\r\n            method: 'POST',\r\n            path: '/send',\r\n            handler: Controllers.Auth.csrf_handshake,\r\n            config: {\r\n                auth: false\r\n            }\r\n        }\r\n    ]);\r\n```\r\n\r\nHapiJS routes handlers:\r\n\r\n```javascript\r\n\r\nexports.generate_csrf = function (request, reply) {\r\n    request.log.info(request.info, 'Request to generate CSRF Token');\r\n    return reply({csrf_token: request.plugins.crumb});\r\n};\r\n\r\nexports.csrf_handshake = function (request, reply) {\r\n   return reply('OK');\r\n};\r\n\r\n```\r\nOn the web side:\r\n\r\n```javascript\r\n\r\n(function () {\r\n\r\n    var form = $(\"#sms-form\");\r\n    var host = \"http://localhost:3002\"; // HAPIJS Host\r\n\r\n    var getAuth = function () {\r\n        $.ajax({\r\n            url: host + \"/generate\",\r\n            jsonp: \"callback\",\r\n            dataType: \"jsonp\",\r\n            success: function( response ) {\r\n                var token = response.csrf_token; \r\n                var input = $('<input name=\"csrf_token\" type=\"hidden\" value=\"'+token+'\">');\r\n                form.append(input);\r\n            },\r\n            error: function (req, status, err) {\r\n                console.log('error');\r\n            }\r\n        });\r\n    };\r\n\r\n    getAuth();\r\n\r\n\r\n    form.on('submit', function (e) {\r\n        e.preventDefault();\r\n\r\n        var authorizationToken = $(e.currentTarget).find('input[name=\"csrf_token\"]').val();\r\n\r\n        console.log(authorizationToken);\r\n        if(authorizationToken) {\r\n            $.ajax({\r\n                type:\"POST\",\r\n                beforeSend: function (request)\r\n                {\r\n                    request.setRequestHeader(\"X-CSRF-Token\", authorizationToken);\r\n                },\r\n                url: host + \"/send\",\r\n                data: {crumb: authorizationToken},\r\n                dataType: \"json\",\r\n                success: function(msg) {\r\n                    console.log(msg);\r\n                }\r\n            });\r\n        }else {\r\n            console.log(\"We're having issues this request\");\r\n        }\r\n\r\n\r\n    });\r\n\r\n})();\r\n\r\n```\r\n\r\nHere's plugin config:\r\n\r\n```javascript\r\n{\r\nregister: require('crumb'),\r\noptions: { restful: false }\r\n}\r\n```\r\n\r\nAlso I noticed that when calling multiple times GET /generate is returning the same CSRF token, not sure how to generate a new one per request. \r\n\r\nWhen adding a debugger to crumb/lib/index.js, I noticed that the they're not the same: \r\n\r\n```javascript\r\n          debugger;\r\n            if (content instanceof Stream) {\r\n\r\n                return reply(Boom.forbidden());\r\n            }\r\n\r\n            if (content[request.route.settings.plugins._crumb.key] !== request.plugins.crumb) {\r\n                return reply(Boom.forbidden());\r\n            }\r\n```\r\n\r\nAm I missing something here ? \r\n"},"comment":{"url":"https://api.github.com/repos/hapijs/crumb/issues/comments/121279721","html_url":"https://github.com/hapijs/crumb/issues/54#issuecomment-121279721","issue_url":"https://api.github.com/repos/hapijs/crumb/issues/54","id":121279721,"user":{"login":"zoe-1","id":1852507,"avatar_url":"https://avatars.githubusercontent.com/u/1852507?v=3","gravatar_id":"","url":"https://api.github.com/users/zoe-1","html_url":"https://github.com/zoe-1","followers_url":"https://api.github.com/users/zoe-1/followers","following_url":"https://api.github.com/users/zoe-1/following{/other_user}","gists_url":"https://api.github.com/users/zoe-1/gists{/gist_id}","starred_url":"https://api.github.com/users/zoe-1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zoe-1/subscriptions","organizations_url":"https://api.github.com/users/zoe-1/orgs","repos_url":"https://api.github.com/users/zoe-1/repos","events_url":"https://api.github.com/users/zoe-1/events{/privacy}","received_events_url":"https://api.github.com/users/zoe-1/received_events","type":"User","site_admin":false},"created_at":"2015-07-14T15:18:24Z","updated_at":"2015-07-14T15:18:24Z","body":"@marlonmantilla @hapijs/university 's current assignment is related to crumb. \r\nFollow instructions in the [README](https://github.com/hapijs/university) to get started.\r\nSpecifics about the assignment are at: [Assignment8](https://github.com/hapijs/university/issues/167).\r\nHopefully, you will join and submit a PR for the current assignment :-)  Doing this assignment should clear your questions about crumb.\r\n\r\nPlus, I made a sample app fulfilling requirements of Assignment8  [here](https://github.com/zoe-1/hapijs-university/tree/assignment8_dev). The app has 100% test coverage and uses crumb in AJAX post requests, so should provide the solutions you are looking for. The [tests code](https://github.com/zoe-1/hapijs-university/blob/assignment8_dev/test/api/login.js) for the login and logout routes should be very relevant too. Cheers!"}}