Unable to generate new token using write API
-
I do not know what you mean.
I call only /api/v3 -
NodeBB version 3. Not the v3 API, they are different things (although I can see how you could be confused).
You're currently on version 2, version 3 is still unreleased.
Both versions have /api/v3, but the csrf generation library is different in NodeBB v2. That's all.
-
sorry for my confusion.
-
@Carlo-Lancia Yes, still works fine:
curl -X POST -H "x-csrf-token: qbdvOXla-rBob0mHA5NBXlFLIbTZJd7z6do0" localhost:4567/api/v3/users/1/tokens --cookie express.sid=s%3A89Lr9fB_95aGYpvh8fnW1HFwvI6i7vWu.jQS5qdiLh1yCVLfhdUChIufHSIysIKGNaIXgzfQ%2Bxns
{ "status": { "code": "ok", "message": "OK" }, "response": { "token": "aa8b3e37-9d75-4f2b-86ab-d90be15b47f7", "uid": 1, "description": "", "timestamp": 1680705230030 } }
-
Thank you for the time you have dedicated to me.
Now I do some tests,
I try to do it. -
@julian
Hi Julian, How are you?
I was able to test your indications, the results are different from what I expected.
The administrative user actually generates the token successfully.While for a new user the indicated sequence does not have the same effect.
Where am I doing wrong?
I add the API calls to the nodeBB system below.
ADMINISTRATIVE USER "Carlo.Merola"
REQUEST LOGIN
curl --request POST \ --url http://localhost:4567/api/v3/utilities/login \ --header 'Content-Type: application/json' \ --cookie express.sid=s%253AkHYV_owxQoxuaVwGKAA5DE0FpgOuW83p.lbtUZdJHW8LEgPy3GLYncwdLXuQTzsfi4ubk%252BZ5IFJo \ --data '{ "username": "Carlo.Merola", "password": "omissis" }'
RESPONSE OK
{ "status": { "code": "ok", "message": "OK" }, "response": { "uid": 3, "username": "Carlo.Merola", "userslug": "carlo-merola", "picture": "/assets/uploads/profile/3-profileavatar-1676988051741.png", "status": "offline", "postcount": 0, "reputation": 0, "email:confirmed": 1, "lastonline": 1681297625750, "flags": null, "banned": false, "banned:expire": 0, "joindate": 1674838394707, "fullname": null, "displayname": "Carlo.Merola", "icon:text": "C", "icon:bgColor": "#673ab7", "joindateISO": "2023-01-27T16:53:14.707Z", "lastonlineISO": "2023-04-12T11:07:05.750Z", "banned_until": 0, "banned_until_readable": "Not Banned" } }
REQUEST CONFIG
curl --request GET \ --url http://localhost:4567/api/config \ --cookie express.sid=s%253AdWjgq6Xe5i388H4VEXhIzyr4um9uVeZB.bvy78e9PYmjNx%252FEmvR07DdjPD8UWvCDC7CyRiNSvI%252FQ
RESPONSE OK
{ "relative_path": "", "upload_url": "/assets/uploads", "asset_base_url": "/assets", "assetBaseUrl": "/assets", "siteTitle": "HyperCuTe", "browserTitle": "HyperCuTe", "titleLayout": "{pageTitle} | {browserTitle}", "showSiteTitle": true, "maintenanceMode": false, "minimumTitleLength": 3, "maximumTitleLength": 255, "minimumPostLength": 8, "maximumPostLength": 32767, "minimumTagsPerTopic": 0, "maximumTagsPerTopic": 5, "minimumTagLength": 3, "maximumTagLength": 15, "undoTimeout": 10000, "useOutgoingLinksPage": false, "allowGuestHandles": false, "allowTopicsThumbnail": true, "usePagination": true, "disableChat": false, "disableChatMessageEditing": false, "maximumChatMessageLength": 3000, "socketioTransports": [ "polling", "websocket" ], "socketioOrigins": "http://localhost:4567:*", "websocketAddress": "", "maxReconnectionAttempts": 5, "reconnectionDelay": 1500, "topicsPerPage": 20, "postsPerPage": 20, "maximumFileSize": 20480, "theme:id": "nodebb-theme-vanilla", "theme:src": "https://cdn.jsdelivr.net/npm/[email protected]/spacelab/bootstrap.min.css", "defaultLang": "it", "userLang": "it", "loggedIn": true, "uid": 3, "cache-buster": "v=88rphh6u1aq", "topicPostSort": "oldest_to_newest", "categoryTopicSort": "newest_to_oldest", "csrf_token": "vtVKfNxM-MmApXIW16ROi22mizlKf6QNyL-4", "searchEnabled": true, "searchDefaultInQuick": "titles", "bootswatchSkin": "", "enablePostHistory": true, "timeagoCutoff": 30, "timeagoCodes": [ "af", "am", "ar", "az-short", "az", "be", "bg", "bs", "ca", "cs", "cy", "da", "de-short", "de", "dv", "el", "en-short", "en", "es-short", "es", "et", "eu", "fa-short", "fa", "fi", "fr-short", "fr", "gl", "he", "hr", "hu", "hy", "id", "is", "it-short", "it", "ja", "jv", "ko", "ky", "lt", "lv", "mk", "nl", "no", "pl", "pt-br-short", "pt-br", "pt-short", "pt", "ro", "rs", "ru", "rw", "si", "sk", "sl", "sq", "sr", "sv", "th", "tr-short", "tr", "uk", "ur", "uz", "vi", "zh-CN", "zh-TW" ], "cookies": { "enabled": false, "message": "This website uses cookies to ensure you get the best experience on our website.", "dismiss": "Got it!", "link": "Learn More", "link_url": "https://www.cookiesandyou.com" }, "thumbs": { "size": 512 }, "iconBackgrounds": [ "#f44336", "#e91e63", "#9c27b0", "#673ab7", "#3f51b5", "#2196f3", "#009688", "#1b5e20", "#33691e", "#827717", "#e65100", "#ff5722", "#795548", "#607d8b" ], "emailPrompt": 1, "useragent": { "isYaBrowser": false, "isAuthoritative": false, "isMobile": false, "isMobileNative": false, "isTablet": false, "isiPad": false, "isiPod": false, "isiPhone": false, "isiPhoneNative": false, "isAndroid": false, "isAndroidNative": false, "isBlackberry": false, "isOpera": false, "isIE": false, "isEdge": false, "isIECompatibilityMode": false, "isSafari": false, "isFirefox": false, "isWebkit": false, "isChrome": false, "isKonqueror": false, "isOmniWeb": false, "isSeaMonkey": false, "isFlock": false, "isAmaya": false, "isPhantomJS": false, "isEpiphany": false, "isDesktop": false, "isWindows": false, "isLinux": false, "isLinux64": false, "isMac": false, "isChromeOS": false, "isBada": false, "isSamsung": false, "isRaspberry": false, "isBot": false, "isCurl": false, "isAndroidTablet": false, "isWinJs": false, "isKindleFire": false, "isSilk": false, "isCaptive": false, "isSmartTV": false, "isUC": false, "isFacebook": false, "isAlamoFire": false, "isElectron": false, "silkAccelerated": false, "browser": "insomnia", "version": "2022.7.5", "os": "unknown", "platform": "unknown", "geoIp": {}, "source": "insomnia/2022.7.5", "isWechat": false }, "acpLang": "it", "openOutgoingLinksInNewTab": false, "topicSearchEnabled": false, "composer-default": {}, "markdown": { "highlight": 1, "highlightLinesLanguageList": [], "theme": "default.css", "defaultHighlightLanguage": "" }, "emojiCustomFirst": false }
REQUEST TOKEN
curl --request POST \ --url http://localhost:4567/api/v3/users/3/tokens \ --header 'x-csrf-token: vtVKfNxM-MmApXIW16ROi22mizlKf6QNyL-4' \ --cookie express.sid=s%253AdWjgq6Xe5i388H4VEXhIzyr4um9uVeZB.bvy78e9PYmjNx%252FEmvR07DdjPD8UWvCDC7CyRiNSvI%252FQ
RESPONSE OK
{ "status": { "code": "ok", "message": "OK" }, "response": { "token": "ac9bfc1e-e31d-4779-b900-71e3c15f5fac", "uid": 3, "description": "", "timestamp": 1681300461177 } }
NEW REGISTERED USER "Soldatino"
REQUEST LOGIN
curl --request POST \ --url http://localhost:4567/api/v3/utilities/login \ --header 'Content-Type: application/json' \ --cookie express.sid=s%253ATiY7RPVN5jBsBLpjCcf28kW_jh4-3R6P.eOp1l18tfazAfL2QvgpD%252BU9zoDv08X9KfJo4rE88O38 \ --data '{ "username": "Soldatino", "password": "omissis" }'
RESPONSE OK
{ "status": { "code": "ok", "message": "OK" }, "response": { "uid": 65, "username": "Soldatino", "userslug": "soldatino", "picture": null, "status": "offline", "postcount": 0, "reputation": 0, "email:confirmed": 1, "lastonline": 1681298877112, "flags": null, "banned": false, "banned:expire": 0, "joindate": 1679315311139, "fullname": null, "displayname": "Soldatino", "icon:text": "S", "icon:bgColor": "#673ab7", "joindateISO": "2023-03-20T12:28:31.139Z", "lastonlineISO": "2023-04-12T11:27:57.112Z", "banned_until": 0, "banned_until_readable": "Not Banned" } }
REQUEST CONFIG
curl --request GET \ --url http://localhost:4567/api/config \ --cookie express.sid=s%253ATiY7RPVN5jBsBLpjCcf28kW_jh4-3R6P.eOp1l18tfazAfL2QvgpD%252BU9zoDv08X9KfJo4rE88O38
RESPONSE OK
{ "relative_path": "", "upload_url": "/assets/uploads", "asset_base_url": "/assets", "assetBaseUrl": "/assets", "siteTitle": "HyperCuTe", "browserTitle": "HyperCuTe", "titleLayout": "{pageTitle} | {browserTitle}", "showSiteTitle": true, "maintenanceMode": false, "minimumTitleLength": 3, "maximumTitleLength": 255, "minimumPostLength": 8, "maximumPostLength": 32767, "minimumTagsPerTopic": 0, "maximumTagsPerTopic": 5, "minimumTagLength": 3, "maximumTagLength": 15, "undoTimeout": 10000, "useOutgoingLinksPage": false, "allowGuestHandles": false, "allowTopicsThumbnail": true, "usePagination": true, "disableChat": false, "disableChatMessageEditing": false, "maximumChatMessageLength": 3000, "socketioTransports": [ "polling", "websocket" ], "socketioOrigins": "http://localhost:4567:*", "websocketAddress": "", "maxReconnectionAttempts": 5, "reconnectionDelay": 1500, "topicsPerPage": 20, "postsPerPage": 20, "maximumFileSize": 20480, "theme:id": "nodebb-theme-vanilla", "theme:src": "https://cdn.jsdelivr.net/npm/[email protected]/spacelab/bootstrap.min.css", "defaultLang": "it", "userLang": "it", "loggedIn": true, "uid": 65, "cache-buster": "v=88rphh6u1aq", "topicPostSort": "oldest_to_newest", "categoryTopicSort": "newest_to_oldest", "csrf_token": "p3Yq9OQ7-O1EpqDzJkX1TvWuJ1JzBvuAydpU", "searchEnabled": true, "searchDefaultInQuick": "titles", "bootswatchSkin": "", "enablePostHistory": true, "timeagoCutoff": 30, "timeagoCodes": [ "af", "am", "ar", "az-short", "az", "be", "bg", "bs", "ca", "cs", "cy", "da", "de-short", "de", "dv", "el", "en-short", "en", "es-short", "es", "et", "eu", "fa-short", "fa", "fi", "fr-short", "fr", "gl", "he", "hr", "hu", "hy", "id", "is", "it-short", "it", "ja", "jv", "ko", "ky", "lt", "lv", "mk", "nl", "no", "pl", "pt-br-short", "pt-br", "pt-short", "pt", "ro", "rs", "ru", "rw", "si", "sk", "sl", "sq", "sr", "sv", "th", "tr-short", "tr", "uk", "ur", "uz", "vi", "zh-CN", "zh-TW" ], "cookies": { "enabled": false, "message": "This website uses cookies to ensure you get the best experience on our website.", "dismiss": "Got it!", "link": "Learn More", "link_url": "https://www.cookiesandyou.com" }, "thumbs": { "size": 512 }, "iconBackgrounds": [ "#f44336", "#e91e63", "#9c27b0", "#673ab7", "#3f51b5", "#2196f3", "#009688", "#1b5e20", "#33691e", "#827717", "#e65100", "#ff5722", "#795548", "#607d8b" ], "emailPrompt": 1, "useragent": { "isYaBrowser": false, "isAuthoritative": false, "isMobile": false, "isMobileNative": false, "isTablet": false, "isiPad": false, "isiPod": false, "isiPhone": false, "isiPhoneNative": false, "isAndroid": false, "isAndroidNative": false, "isBlackberry": false, "isOpera": false, "isIE": false, "isEdge": false, "isIECompatibilityMode": false, "isSafari": false, "isFirefox": false, "isWebkit": false, "isChrome": false, "isKonqueror": false, "isOmniWeb": false, "isSeaMonkey": false, "isFlock": false, "isAmaya": false, "isPhantomJS": false, "isEpiphany": false, "isDesktop": false, "isWindows": false, "isLinux": false, "isLinux64": false, "isMac": false, "isChromeOS": false, "isBada": false, "isSamsung": false, "isRaspberry": false, "isBot": false, "isCurl": false, "isAndroidTablet": false, "isWinJs": false, "isKindleFire": false, "isSilk": false, "isCaptive": false, "isSmartTV": false, "isUC": false, "isFacebook": false, "isAlamoFire": false, "isElectron": false, "silkAccelerated": false, "browser": "insomnia", "version": "2022.7.5", "os": "unknown", "platform": "unknown", "geoIp": {}, "source": "insomnia/2022.7.5", "isWechat": false }, "acpLang": "it", "openOutgoingLinksInNewTab": false, "topicSearchEnabled": false, "composer-default": {}, "markdown": { "highlight": 1, "highlightLinesLanguageList": [], "theme": "default.css", "defaultHighlightLanguage": "" }, "emojiCustomFirst": false }
REQUEST TOKEN
curl --request POST \ --url http://localhost:4567/api/v3/users/65/tokens \ --header 'x-csrf-token: p3Yq9OQ7-O1EpqDzJkX1TvWuJ1JzBvuAydpU' \ --cookie express.sid=s%253ATiY7RPVN5jBsBLpjCcf28kW_jh4-3R6P.eOp1l18tfazAfL2QvgpD%252BU9zoDv08X9KfJo4rE88O38
RESPONSE NOK
{ "status": { "code": "forbidden", "message": "You do not have enough privileges for this action." }, "response": {} }
-
Hi @Carlo-Lancia, I did some digging into the history of the implementation and it seems to be that this route was not intended to be called by regular users. The logic restricting access to administrators has been there since the beginning.
This is not to say that it will always be this way. If I had to guess my thought process (again, this was nearly three years ago), I would fathom that I restricted access because allowing regular users to create their own tokens necessitates building out a custom UI for users to manage their tokens, as well as a corresponding GET route to retrieve tokens, and a backend for toggling the feature on and off, etc. My focus at that time was to port the logic from the Write API plugin as quickly as possible.
-
In the meantime, if you wish to allow users to create their own tokens (either by using another token or by using a cookie sesson), go to the
usersAPI.generateToken
method insrc/api/users.js
, and remove the following line:await hasAdminPrivilege(caller.uid, 'settings');
That is the simplest way to bypass the security of the controller so that anyone can create a token for themselves.
-
Hi Julian,
I just modified the file "src/controllers/write/users.js", as you indicated. Now I can generate the token.
Ok!
Grazie -