{"_id":"@authok/authok-spa-js","_rev":"6-399ae649537fe00e30b0b1d3d6d08c7a","time":{"created":"2022-01-16T10:50:54.582Z","1.19.4":"2022-01-16T06:18:41.783Z","modified":"2022-04-04T16:32:07.322Z","1.19.5":"2022-01-16T10:50:54.815Z","1.19.6":"2022-01-19T17:11:51.079Z","1.19.7":"2022-03-15T13:29:09.794Z"},"name":"@authok/authok-spa-js","dist-tags":{"latest":"1.19.7"},"versions":{"1.19.5":{"author":{"name":"Authok"},"name":"@authok/authok-spa-js","description":"Authok SDK for Single Page Applications using Authorization Code Grant Flow with PKCE","license":"MIT","version":"1.19.5","main":"dist/lib/authok-spa-js.cjs.js","types":"dist/typings/index.d.ts","module":"dist/authok-spa-js.production.esm.js","scripts":{"dev":"rimraf dist && rollup -c --watch","start":"npm run dev","docs":"typedoc --options ./typedoc.js --module commonjs","build":"rimraf dist && rollup -m -c --environment NODE_ENV:production && npm run test:es-check","build:stats":"npm run build -- --environment WITH_STATS:true && open stats.html","lint:security":"eslint ./src --ext ts --no-eslintrc --config ./.eslintrc.security","test":"jest --coverage --silent","test:watch":"jest --coverage --watch","test:debug":"node --inspect node_modules/.bin/jest --runInBand","test:open:integration":"cypress open","test:watch:integration":"concurrently --raw npm:dev 'npm:test:open:integration'","test:es-check":"npm run test:es-check:es5 && npm run test:es-check:es2015:module","test:es-check:es5":"es-check es5 'dist/authok-spa-js.production.js'","test:es-check:es2015:module":"es-check es2015 'dist/authok-spa-js.production.esm.js' --module ","test:integration:server":"npm run dev","test:integration:tests":"wait-on http://localhost:3000/ && cypress run","test:integration":"concurrently --raw --kill-others --success first npm:test:integration:server npm:test:integration:tests","serve:coverage":"serve coverage/lcov-report -n","serve:stats":"serve bundle-stats -n","print-bundle-size":"node ./scripts/print-bundle-size","prepack":"npm run build && node ./scripts/prepack","publish:cdn":"ccu --trace"},"devDependencies":{"@rollup/plugin-replace":"^2.4.2","@types/cypress":"^1.1.3","@types/jest":"^27.0.2","@typescript-eslint/eslint-plugin-tslint":"^4.33.0","@typescript-eslint/parser":"^4.33.0","browserstack-cypress-cli":"1.8.1","cli-table":"^0.3.6","codecov":"^3.8.3","concurrently":"^6.4.0","cypress":"7.2.0","es-check":"^6.1.1","eslint":"^7.32.0","gzip-size":"^6.0.0","husky":"^7.0.4","idtoken-verifier":"^2.2.2","jest":"^27.3.1","jest-junit":"^13.0.0","jest-localstorage-mock":"^2.4.18","jsonwebtoken":"^8.5.1","oidc-provider":"^7.10.1","pem":"^1.14.4","prettier":"^2.4.1","pretty-quick":"^3.1.2","qss":"^2.0.3","rimraf":"^3.0.2","rollup":"^2.60.0","rollup-plugin-analyzer":"^4.0.0","rollup-plugin-commonjs":"^10.1.0","rollup-plugin-dev":"^1.1.3","rollup-plugin-livereload":"^2.0.5","rollup-plugin-node-resolve":"^5.2.0","rollup-plugin-sourcemaps":"^0.6.3","rollup-plugin-terser":"^7.0.2","rollup-plugin-typescript2":"^0.30.0","rollup-plugin-visualizer":"^5.5.2","rollup-plugin-web-worker-loader":"^1.6.1","serve":"^12.0.1","ts-jest":"^27.0.7","tslib":"^2.3.1","tslint":"^6.1.3","tslint-config-security":"^1.16.0","typedoc":"0.18.0","typescript":"^4.4.4","wait-on":"^6.0.0"},"dependencies":{"abortcontroller-polyfill":"^1.7.3","browser-tabs-lock":"^1.2.15","core-js":"^3.20.0","es-cookie":"^1.3.2","fast-text-encoding":"^1.0.3","promise-polyfill":"^8.2.1","unfetch":"^4.2.0"},"repository":{"type":"git","url":"git://github.com/authok/authok-spa-js.git"},"bugs":{"url":"https://github.com/authok/authok-spa-js/issues"},"homepage":"https://github.com/authok/authok-spa-js#readme","keywords":["authok","login","Authorization Code Grant Flow","PKCE","Single Page Application authentication","SPA authentication"],"ccu":{"name":"authok-spa-js","cdn":"https://cdn.authok.com","mainBundleFile":"authok-spa-js.production.js","bucket":"assets.us.authok.com","localPath":"dist","digest":{"hashes":["sha384"],"extensions":[".js"]}},"husky":{"hooks":{"pre-commit":"pretty-quick --staged"}},"gitHead":"0d650994e0307e2f4dd60cc5d35a98abf64cd1b1","_id":"@authok/authok-spa-js@1.19.5","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-hTZiD5VoohNPs6eRXFmHhPpbZirDTsvuQNiL0sFgfEg8Veo9L7fZD01vLxHz5oQg0J3/OF/jg9zlKHRdDa77EA==","shasum":"e319c2dad8f183e1a2d780085d116edcecfd9d9e","tarball":"https://registry.npmjs.org/@authok/authok-spa-js/-/authok-spa-js-1.19.5.tgz","fileCount":62,"unpackedSize":2602977,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh4/iOCRA9TVsSAnZWagAATeIP/1fTT7N676IiSzCQ39fb\nQOkqgEi+XfAV1XKc3jFD++bfE5xvH88OobUtNxPLJci+yFMIM00hBywuO+8G\n49CytUebvcdWmMpLz2wAbVxSe1wUsQoBJmcYurXSwJhKwD8OpfKMaX0X9AhL\nuozx0B/yrapB4JgrVtAl/uo2sTNzRiIbeSWSth0MhapYFfEnwBOcyg2TMdiT\n4R+S3Xj6A3dopVb+PfJk4bYl3Nee5K19h613FCmYM1nHuw3vkGy0NHKC3Ptf\na95NKsnQKQw6eJeGEJY7eQgo2mBD3H1LSFrZ4Ztby4E0tCrqlaehR4FowE1y\nJPWMC6Ysp/zqmny84d/7UPJsU2gjHCXbnNzbn1A1OsgKd/Mc8PN7znFlmi75\n29VgTpR0NFv4+kO6L4nef1Z5opGWzzBiuQR1EKq8ciyApTsvixNNBiFQNn/0\nh1fFV2MhjCnDD37Z0muVfE1rCjPZ153fGr6JXLPEw+e0qDBu5vEo3R/3Tlj8\nzx0Y8RR5J0x+3ZB47rNitOIrgCamBGeiqtnEHXlDCUZmv9Jxj4QXlu1XfhD+\nhI6+baDiNtTbkg5fSSAYcIWsYDvLBngNVa8nr/nDcv7cBTsebMJa+P5Uu8zG\n6PoOcZZI6yX6orGVdkhojYOM9t2Pdyxj6J4xeJjx1os3qrs9GGoRvIMJYC8t\n5Dnp\r\n=9gc5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDBttP+Ed4aT/vXRORxxylQZLvxAb4MfGwuZnyMBsoTTwIhAK9wXga26ip2ewgAPP48ii2udzuOLNRXH4+N7FT2CvH5"}]},"_npmUser":{"name":"newtalentxp","email":"newtalentxp@126.com"},"directories":{},"maintainers":[{"name":"newtalentxp","email":"newtalentxp@126.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/authok-spa-js_1.19.5_1642330254625_0.3633040819828899"},"_hasShrinkwrap":false},"1.19.6":{"author":{"name":"Authok"},"name":"@authok/authok-spa-js","description":"Authok SDK for Single Page Applications using Authorization Code Grant Flow with PKCE","license":"MIT","version":"1.19.6","main":"dist/lib/authok-spa-js.cjs.js","types":"dist/typings/index.d.ts","module":"dist/authok-spa-js.production.esm.js","scripts":{"dev":"rimraf dist && rollup -c --watch","start":"npm run dev","docs":"typedoc --options ./typedoc.js --module commonjs","build":"rimraf dist && rollup -m -c --environment NODE_ENV:production && npm run test:es-check","build:stats":"npm run build -- --environment WITH_STATS:true && open stats.html","lint:security":"eslint ./src --ext ts --no-eslintrc --config ./.eslintrc.security","test":"jest --coverage --silent","test:watch":"jest --coverage --watch","test:debug":"node --inspect node_modules/.bin/jest --runInBand","test:open:integration":"cypress open","test:watch:integration":"concurrently --raw npm:dev 'npm:test:open:integration'","test:es-check":"npm run test:es-check:es5 && npm run test:es-check:es2015:module","test:es-check:es5":"es-check es5 'dist/authok-spa-js.production.js'","test:es-check:es2015:module":"es-check es2015 'dist/authok-spa-js.production.esm.js' --module ","test:integration:server":"npm run dev","test:integration:tests":"wait-on http://localhost:3000/ && cypress run","test:integration":"concurrently --raw --kill-others --success first npm:test:integration:server npm:test:integration:tests","serve:coverage":"serve coverage/lcov-report -n","serve:stats":"serve bundle-stats -n","print-bundle-size":"node ./scripts/print-bundle-size","prepack":"npm run build && node ./scripts/prepack","publish:cdn":"ccu --trace"},"devDependencies":{"@rollup/plugin-replace":"^2.4.2","@types/cypress":"^1.1.3","@types/jest":"^27.0.2","@typescript-eslint/eslint-plugin-tslint":"^4.33.0","@typescript-eslint/parser":"^4.33.0","browserstack-cypress-cli":"1.8.1","cli-table":"^0.3.6","codecov":"^3.8.3","concurrently":"^6.4.0","cypress":"7.2.0","es-check":"^6.1.1","eslint":"^7.32.0","gzip-size":"^6.0.0","husky":"^7.0.4","idtoken-verifier":"^2.2.2","jest":"^27.3.1","jest-junit":"^13.0.0","jest-localstorage-mock":"^2.4.18","jsonwebtoken":"^8.5.1","oidc-provider":"^7.10.1","pem":"^1.14.4","prettier":"^2.4.1","pretty-quick":"^3.1.2","qss":"^2.0.3","rimraf":"^3.0.2","rollup":"^2.60.0","rollup-plugin-analyzer":"^4.0.0","rollup-plugin-commonjs":"^10.1.0","rollup-plugin-dev":"^1.1.3","rollup-plugin-livereload":"^2.0.5","rollup-plugin-node-resolve":"^5.2.0","rollup-plugin-sourcemaps":"^0.6.3","rollup-plugin-terser":"^7.0.2","rollup-plugin-typescript2":"^0.30.0","rollup-plugin-visualizer":"^5.5.2","rollup-plugin-web-worker-loader":"^1.6.1","serve":"^12.0.1","ts-jest":"^27.0.7","tslib":"^2.3.1","tslint":"^6.1.3","tslint-config-security":"^1.16.0","typedoc":"0.18.0","typescript":"^4.4.4","wait-on":"^6.0.0"},"dependencies":{"abortcontroller-polyfill":"^1.7.3","browser-tabs-lock":"^1.2.15","core-js":"^3.20.0","es-cookie":"^1.3.2","fast-text-encoding":"^1.0.3","promise-polyfill":"^8.2.1","unfetch":"^4.2.0"},"repository":{"type":"git","url":"git://github.com/authok/authok-spa-js.git"},"bugs":{"url":"https://github.com/authok/authok-spa-js/issues"},"homepage":"https://github.com/authok/authok-spa-js#readme","keywords":["authok","login","Authorization Code Grant Flow","PKCE","Single Page Application authentication","SPA authentication"],"ccu":{"name":"authok-spa-js","cdn":"https://cdn.authok.cn","mainBundleFile":"authok-spa-js.production.js","bucket":"assets.cn.authok.cn","localPath":"dist","digest":{"hashes":["sha384"],"extensions":[".js"]}},"husky":{"hooks":{"pre-commit":"pretty-quick --staged"}},"gitHead":"dcce006774f6852bf2660fcc206cde36fcca69c1","_id":"@authok/authok-spa-js@1.19.6","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-saWtzx4Hd4CwKHy+/NmuCxImSIyuJ71bEmS2NNaZK92ksdUcaGaXv/2fR4yI/XHC7HBeL1H1KV88EPQpDgA9uw==","shasum":"50d70a19a667e251eca320871450ef336b524d0c","tarball":"https://registry.npmjs.org/@authok/authok-spa-js/-/authok-spa-js-1.19.6.tgz","fileCount":62,"unpackedSize":2601996,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh6EZXCRA9TVsSAnZWagAAj94P/iWhPnr+LExkMJ6FXnHL\ngmYRseBmWyzDhUL08zMs3T89NJPagMKYnlYrXBtlYTEq/Q2OPg2wiOxJzZEA\nYPPN7HKMz3PG63j/cfA6io4UPZS06ibmwx5DSwdhLXbWW2WJQf/IWH47Tbtd\nlZFtNwXPnGdmFC1Bw7NV0Bhk112DtruiLpUQACpxhb7EclhaSAdCti/BVe+R\n/5tSon240BXe30PQZRFGQV3etLmLhdHn8ITvjNxRzIUitBu5Dfx37j2fUXMn\ntyBmZcOAkC38H0o+a1Ie7kKfanbDKprz7fBIHowkkZ6wpWmimf+FRZjNzPzi\n+EYR/4bgl+jYJH9eaeL3Z4vm/gUIIklCiFhfnBamkuTxRFsgRUFpGovrQtMO\ntiuHNnLgN37DhGTLUZ3oJzryCcQvxdNFBcL06oEcW4JwasOY9BOeboeOzCav\nC2wLKw5ZnNTevcWI2EMFGsJoMugSmYOLYKkGvRt9rNCXySqfFG7o6xiv+s1W\nomGcB7iGORi5EP2ANxuZVQgWcJsyBo89tEh/aoAHC2LRWviXLf+J8wYDtBAB\nR/wk/gXedW/WRhPvjjyfIzSFIzqNstRaNXsf7p7kwGbng3EGYVLdwV5ywimR\niYvZqeKDfZk4wDDyWX1wUAln02vAKgXhe2syJK74jTVVn8LBFbXvYjRjU29Q\nKIM+\r\n=DvXv\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD++9nRAx6DLbc94wGZHACF/AVa9ScSFvKf3+s7SkPEMAIhANX2GuQ05F369QLDGpcYz2x2U/dXLzSIY5ZFDZkk9MOR"}]},"_npmUser":{"name":"newtalentxp","email":"newtalentxp@126.com"},"directories":{},"maintainers":[{"name":"newtalentxp","email":"newtalentxp@126.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/authok-spa-js_1.19.6_1642612310748_0.06513676099932275"},"_hasShrinkwrap":false},"1.19.7":{"author":{"name":"Authok"},"name":"@authok/authok-spa-js","description":"Authok SDK for Single Page Applications using Authorization Code Grant Flow with PKCE","license":"MIT","version":"1.19.7","main":"dist/lib/authok-spa-js.cjs.js","types":"dist/typings/index.d.ts","module":"dist/authok-spa-js.production.esm.js","scripts":{"dev":"rimraf dist && rollup -c --watch","start":"npm run dev","docs":"typedoc --options ./typedoc.js --module commonjs","build":"rimraf dist && rollup -m -c --environment NODE_ENV:production && npm run test:es-check","build:stats":"npm run build -- --environment WITH_STATS:true && open stats.html","lint:security":"eslint ./src --ext ts --no-eslintrc --config ./.eslintrc.security","test":"jest --coverage --silent","test:watch":"jest --coverage --watch","test:debug":"node --inspect node_modules/.bin/jest --runInBand","test:open:integration":"cypress open","test:watch:integration":"concurrently --raw npm:dev 'npm:test:open:integration'","test:es-check":"npm run test:es-check:es5 && npm run test:es-check:es2015:module","test:es-check:es5":"es-check es5 'dist/authok-spa-js.production.js'","test:es-check:es2015:module":"es-check es2015 'dist/authok-spa-js.production.esm.js' --module ","test:integration:server":"npm run dev","test:integration:tests":"wait-on http://localhost:3000/ && cypress run","test:integration":"concurrently --raw --kill-others --success first npm:test:integration:server npm:test:integration:tests","serve:coverage":"serve coverage/lcov-report -n","serve:stats":"serve bundle-stats -n","print-bundle-size":"node ./scripts/print-bundle-size","prepack":"npm run build && node ./scripts/prepack","publish:cdn":"ccu --trace"},"devDependencies":{"@rollup/plugin-replace":"^2.4.2","@types/cypress":"^1.1.3","@types/jest":"^27.0.2","@typescript-eslint/eslint-plugin-tslint":"^4.33.0","@typescript-eslint/parser":"^4.33.0","browserstack-cypress-cli":"1.8.1","cli-table":"^0.3.6","codecov":"^3.8.3","concurrently":"^6.4.0","cypress":"7.2.0","es-check":"^6.1.1","eslint":"^7.32.0","gzip-size":"^6.0.0","husky":"^7.0.4","idtoken-verifier":"^2.2.2","jest":"^27.3.1","jest-junit":"^13.0.0","jest-localstorage-mock":"^2.4.18","jsonwebtoken":"^8.5.1","oidc-provider":"^7.10.1","pem":"^1.14.4","prettier":"^2.4.1","pretty-quick":"^3.1.2","qss":"^2.0.3","rimraf":"^3.0.2","rollup":"^2.60.0","rollup-plugin-analyzer":"^4.0.0","rollup-plugin-commonjs":"^10.1.0","rollup-plugin-dev":"^1.1.3","rollup-plugin-livereload":"^2.0.5","rollup-plugin-node-resolve":"^5.2.0","rollup-plugin-sourcemaps":"^0.6.3","rollup-plugin-terser":"^7.0.2","rollup-plugin-typescript2":"^0.30.0","rollup-plugin-visualizer":"^5.5.2","rollup-plugin-web-worker-loader":"^1.6.1","serve":"^12.0.1","ts-jest":"^27.0.7","tslib":"^2.3.1","tslint":"^6.1.3","tslint-config-security":"^1.16.0","typedoc":"0.18.0","typescript":"^4.4.4","wait-on":"^6.0.0"},"dependencies":{"abortcontroller-polyfill":"^1.7.3","browser-tabs-lock":"^1.2.15","core-js":"^3.20.0","es-cookie":"^1.3.2","fast-text-encoding":"^1.0.3","promise-polyfill":"^8.2.1","unfetch":"^4.2.0"},"repository":{"type":"git","url":"git://github.com/authok/authok-spa-js.git"},"bugs":{"url":"https://github.com/authok/authok-spa-js/issues"},"homepage":"https://github.com/authok/authok-spa-js#readme","keywords":["authok","login","Authorization Code Grant Flow","PKCE","Single Page Application authentication","SPA authentication"],"ccu":{"name":"authok-spa-js","cdn":"https://cdn.authok.cn","mainBundleFile":"authok-spa-js.production.js","bucket":"assets.cn.authok.cn","localPath":"dist","digest":{"hashes":["sha384"],"extensions":[".js"]}},"husky":{"hooks":{"pre-commit":"pretty-quick --staged"}},"gitHead":"1821fe28676376d4902ca1273f3d016fba2d8e80","_id":"@authok/authok-spa-js@1.19.7","_nodeVersion":"16.13.1","_npmVersion":"8.1.2","dist":{"integrity":"sha512-eKy4bLI7f1wklQY44M9RGmFqptz4G3TmbVjFOORAuYYJscBLcivWi/kKN2uDAAGAU/GHmy1A7BOykgHyPu74XQ==","shasum":"143d88483ed4deb1c43dfeaa3c433daa21aa37f0","tarball":"https://registry.npmjs.org/@authok/authok-spa-js/-/authok-spa-js-1.19.7.tgz","fileCount":62,"unpackedSize":2602023,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiMJSlACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpfXg/9Go+RpGA0fBIcccSySh9jsugwoA1cLn3illi+nTSwTUrOaQtG\r\nIxIeDT7d1HXDmpSzsUSoeg3RknZNE1dG0lfMipuSK3EQP9koNZV9r8cJV0bA\r\nTYOt7dCeZaNNIBaMO9q+xh0clD+nAkdItYI/lNMB5xluw3gcCa8IjBY3il7W\r\nNvAYOkU0e1taXZtd9cdmKA+kpRtdTI6iMO92BVIbCTkcNyhBdJ21rYB/bmo6\r\ny0CQ/kpv4YiXGPxY7uGlhxeEjk9YOZGIGiR20se9mO3HvtZVO/Kb7/n+Ss+O\r\np+JmHkMIrcbr6tUApmvBff1eB6QYZ+AqOhnIZeFx0OTEBaS+XvCSKjRYctZ0\r\nE6zkv4Ol964gthw3VUyE1bv08iH1TgW/xfCWtIRcffK6V/2DmsieN3Fj4BHL\r\nPA2dsST5dIQWqhkTmOwghZc93sv9N0YwN3y+ShjrXRg4EWF/75U9OVTkM4gN\r\nUhLGxArVdV0iGLeoM+TKRZjhL/rZiTvg+wEPsouhEFJZm2ixcf5pBKEEBH/y\r\nt9M4D245vpBRNyxnpsobHwcWOB6sOgrIoFMHnf47h49Xx4pN0QK9NgSYrHYw\r\nLicmPGoawUJ6hpXoXJRLSCwl8mopeiONoPncQKB2esmCvlU3B/gb/SxI/t4q\r\nDkUZ7IJDOkYzZVaqpJTMKtjIJ4+eHaDsU5s=\r\n=qWGs\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCTr0p9PN+k8VIvyBIk7uVbALC50HSJkk6OrdPtcvk3DAIhAKnCqAjZhkx3TF0LWLXEYyewFUt8OGMBEQGpF7+heR9I"}]},"_npmUser":{"name":"newtalentxp","email":"newtalentxp@126.com"},"directories":{},"maintainers":[{"name":"newtalentxp","email":"newtalentxp@126.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/authok-spa-js_1.19.7_1647350949573_0.903013561958586"},"_hasShrinkwrap":false}},"maintainers":[{"name":"newtalentxp","email":"newtalentxp@126.com"}],"description":"Authok SDK for Single Page Applications using Authorization Code Grant Flow with PKCE","homepage":"https://github.com/authok/authok-spa-js#readme","keywords":["authok","login","Authorization Code Grant Flow","PKCE","Single Page Application authentication","SPA authentication"],"repository":{"type":"git","url":"git://github.com/authok/authok-spa-js.git"},"author":{"name":"Authok"},"bugs":{"url":"https://github.com/authok/authok-spa-js/issues"},"license":"MIT","readme":"# @authok/authok-spa-js\n\n针对单页面应用(SPA)的 Authok SDK, 采用 [基于 PKCE 的认证码授权流程](https://docs.authok.cn/api-auth/tutorials/authorization-code-grant-pkce).\n\n[![CircleCI](https://circleci.com/gh/authok/authok-spa-js.svg?style=svg)](https://circleci.com/gh/authok/authok-spa-js)\n![Release](https://img.shields.io/github/v/release/authok/authok-spa-js)\n[![Codecov](https://img.shields.io/codecov/c/github/authok/authok-spa-js)](https://codecov.io/gh/authok/authok-spa-js)\n![Downloads](https://img.shields.io/npm/dw/@authok/authok-spa-js)\n[![License](https://img.shields.io/:license-mit-blue.svg?style=flat)](https://opensource.org/licenses/MIT)\n\n## 目录\n\n- [@authok/authok-spa-js](#authokauthok-spa-js)\n  - [目录](#目录)\n  - [文档](#文档)\n  - [安装](#安装)\n  - [开始](#开始)\n    - [Authok 配置](#authok-配置)\n    - [创建 client](#创建-client)\n    - [1 - 登录](#1---登录)\n    - [2 - 调用 API](#2---调用-api)\n    - [3 - 退登(Logout)](#3---退登logout)\n    - [数据缓存选项](#数据缓存选项)\n      - [创建自定义缓存](#创建自定义缓存)\n    - [刷新令牌(Refresh Token)](#刷新令牌refresh-token)\n      - [刷新令牌回退](#刷新令牌回退)\n    - [组织](#组织)\n      - [登录组织](#登录组织)\n      - [接受用户邀请](#接受用户邀请)\n    - [高级选项](#高级选项)\n  - [贡献](#贡献)\n  - [支持 + 反馈](#支持--反馈)\n  - [常见问题](#常见问题)\n  - [安全风险报告](#安全风险报告)\n  - [Authok 是什么?](#authok-是什么)\n  - [许可](#许可)\n\n## 文档\n\n- [文档](https://authok.cn/docs/libraries/authok-spa-js)\n- [API 参考](https://authok.github.io/authok-spa-js/)\n- [从 Authok.js 升级到 Authok 单页应用 SDK](https://docs.authok.cn/libraries/authok-spa-js/migrate-from-authokjs)\n\n## 安装\n\n从 CDN 安装:\n\n```html\n<script src=\"https://cdn.authok.cn/js/authok-spa-js/1.19/authok-spa-js.production.js\"></script>\n```\n\n使用 [npm](https://npmjs.org):\n\n```sh\nnpm install @authok/authok-spa-js\n```\n\n使用 [yarn](https://yarnpkg.com):\n\n```sh\nyarn add @authok/authok-spa-js\n```\n\n## 开始\n\n### Authok 配置\n\n在 [Authok Dashboard](https://manage.authok.cn/#/applications) 中创建一个 **单页应用** .\n\n> **如果您使用的现有应用**, 确认您是否在单页应用中做了如下配置:\n>\n> - 点击应用页面的 \"设置\" 标签栏.\n> - 确保 \"应用属性\" 下面的 \"Token Endpoint Authentication Method\" 设置为 \"None\"\n> - 滚动到页面下方并点击 \"显示高级设置\" 链接.\n> - 在 \"高级设置\" 中点击 \"OAuth\" 标签.\n> - 确保 \"JsonWebToken Signature Algorithm\" 设置为 `RS256` 并且 \"OIDC Conformant\" 是开启的.\n\n接下来，在应用 >> “设置\" >> \"应用 URIs\" 部分配置如下 URL:\n\n- **Allowed Callback URLs**: `http://localhost:3000`\n- **Allowed Logout URLs**: `http://localhost:3000`\n- **Allowed Web Origins**: `http://localhost:3000`\n\n> 这些 URLs 对应的是应用运行的来源(origin). **Allowed Callback URLs** 还包含应用处理回调的具体路径 (见下文).\n\n注意 \"基本信息\" 中的 **Client ID** 和 **Domain**. 下一步需要用到这些值.\n\n### 创建 client\n\n在渲染或初始化应用程序之前创建 `AuthokClient` 实例. 您应该仅创建唯一一个 client 实例.\n\n```js\nimport createAuthokClient from '@authok/authok-spa-js';\n\n//with async/await\nconst authok = await createAuthokClient({\n  domain: '<AUTHOK_DOMAIN>',\n  client_id: '<AUTHOK_CLIENT_ID>',\n  redirect_uri: '<MY_CALLBACK_URL>'\n});\n\n//with promises\ncreateAuthokClient({\n  domain: '<AUTHOK_DOMAIN>',\n  client_id: '<AUTHOK_CLIENT_ID>',\n  redirect_uri: '<MY_CALLBACK_URL>'\n}).then(authok => {\n  //...\n});\n\n//或者，您可以自行实例化 client\nimport { AuthokClient } from '@authok/authok-spa-js';\n\nconst authok = new AuthokClient({\n  domain: '<AUTHOK_DOMAIN>',\n  client_id: '<AUTHOK_CLIENT_ID>',\n  redirect_uri: '<MY_CALLBACK_URL>'\n});\n\n//如果自行实例化，您需要自行检查会话\ntry {\n  await getTokenSilently();\n} catch (error) {\n  if (error.error !== 'login_required') {\n    throw error;\n  }\n}\n```\n\n### 1 - 登录\n\n```html\n<button id=\"login\">登录</button>\n```\n\n```js\n//with async/await\n\n//重定向到统一登录页面\ndocument.getElementById('login').addEventListener('click', async () => {\n  await authok.loginWithRedirect();\n});\n\n//在回调路由中 (<MY_CALLBACK_URL>)\nwindow.addEventListener('load', async () => {\n  const redirectResult = await authok.handleRedirectCallback();\n  //登录成功. 您可以获取用户档案:\n  const user = await authok.getUser();\n  console.log(user);\n});\n\n//with promises\n\n//重定向到统一登录页面\ndocument.getElementById('login').addEventListener('click', () => {\n  authok.loginWithRedirect().catch(() => {\n    //重定向发生错误\n  });\n});\n\n//在回调路由中 (<MY_CALLBACK_URL>)\nwindow.addEventListener('load', () => {\n  authok.handleRedirectCallback().then(redirectResult => {\n    //登录成功. 您可以获取用户档案:\n    authok.getUser().then(user => {\n      console.log(user);\n    });\n  });\n});\n```\n\n### 2 - 调用 API\n\n```html\n<button id=\"call-api\">调用 API</button>\n```\n\n```js\n//with async/await\ndocument.getElementById('call-api').addEventListener('click', async () => {\n  const accessToken = await authok.getTokenSilently();\n  const result = await fetch('https://myapi.com', {\n    method: 'GET',\n    headers: {\n      Authorization: `Bearer ${accessToken}`\n    }\n  });\n  const data = await result.json();\n  console.log(data);\n});\n\n//with promises\ndocument.getElementById('call-api').addEventListener('click', () => {\n  authok\n    .getTokenSilently()\n    .then(accessToken =>\n      fetch('https://myapi.com', {\n        method: 'GET',\n        headers: {\n          Authorization: `Bearer ${accessToken}`\n        }\n      })\n    )\n    .then(result => result.json())\n    .then(data => {\n      console.log(data);\n    });\n});\n```\n\n### 3 - 退登(Logout)\n\n```html\n<button id=\"logout\">退登</button>\n```\n\n```js\nimport createAuthokClient from '@authok/authok-spa-js';\n\ndocument.getElementById('logout').addEventListener('click', () => {\n  authok.logout();\n});\n```\n\n您可以在注销后将用户重定向回您的应用. 这个 URL 必须在 [Authok Dashboard](https://manage.authok.cn) >> 应用 >> **Allowed Logout URLs** 中进行配置:\n\n```js\nauthok.logout({\n  return_to: 'https://your.custom.url.example.com/'\n});\n```\n\n### 数据缓存选项\n\n可以配置 SDK 在内存或本地存储中缓存 ID 令牌和访问令牌. 默认是在内存中. 可以在创建 Authok client 时通过 `cacheLocation` 选项指定.\n\n使用内存模式无需进行选项设置. 使用 本地存储(local storage) 模式, 需设置 `cacheLocation`:\n\n```js\nawait createAuthokClient({\n  domain: '<AUTHOK_DOMAIN>',\n  client_id: '<AUTHOK_CLIENT_ID>',\n  redirect_uri: '<MY_CALLBACK_URL>',\n  cacheLocation: 'localstorage' // valid values are: 'memory' or 'localstorage'\n});\n```\n\n**重要:** 此功能允许将 **ID 和访问令牌** 等数据缓存存储在本地存储中. 使用此选项会给应用程序带来安全风险, 所以 **不要轻易使用**. 应特别注意抵御 XSS 攻击, 避免令牌从本地存储被盗的风险.\n\n#### 创建自定义缓存\n\n可以配置 SDK 使用应用自定义缓存. 比如您有更安全的令牌存储可被使用, 例如混合移动应用程序中.\n\n通过设置 SDK 配置的 `cache` 属性来进行自定义.\n\ncache 对象需要实现如下函数. 所有函数都可以返回 Promise 或静态值.\n\n| 签名                             | 返回值                         | 描述                                                                                                                                                                                                  |\n| -------------------------------- | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `get(key)`                       | Promise<object> 或 object      | 返回找到的对象, 没有找到返回 `undefined`                                                                                                                                                              |\n| `set(key: string, object: any) ` | Promise<void> 或 void          | 设置条目到缓存                                                                                                                                                                                        |\n| `remove(key)`                    | Promise<void> 或 void          | 从缓存删除条目, 条目未找到不作任何处理                                                                                                                                                                |\n| `allKeys()`                      | Promise<string[]> 或 string [] | (可选) 如果您的缓存可以返回所有缓存条目的 key 列表. 否则，SDK 会在内部自行记录 key 清单. **注意**: SDK 使用的 key 带有前缀 `@@authokspajs@@`, 如果您只想返回此 SDK 使用的 key, 可以通过此前缀进行过滤 |\n\n下面是一个自定义缓存的示例, 它使用 `sessionStorage`:\n\n```js\nconst sessionStorageCache = {\n  get: function (key) {\n    return JSON.parse(sessionStorage.getItem(key));\n  },\n\n  set: function (key, value) {\n    sessionStorage.setItem(key, JSON.stringify(value));\n  },\n\n  remove: function (key) {\n    sessionStorage.removeItem(key);\n  },\n\n  // Optional\n  allKeys: function () {\n    return Object.keys(sessionStorage);\n  }\n};\n\nawait createAuthokClient({\n  domain: '<AUTHOK_DOMAIN>',\n  client_id: '<AUTHOK_CLIENT_ID>',\n  redirect_uri: '<MY_CALLBACK_URL>',\n  cache: sessionStorageCache\n});\n```\n\n**注意:** 如果 `cache` 和 `cacheLocation` 都设置的情况下 `cache` 优先级更高. 同时设置的情况下控制台会出现警告.\n\n我们同样暴露了 `InMemoryCache` 和 `LocalStorageCache` 的实现, 这样便于您参考实现.\n\n### 刷新令牌(Refresh Token)\n\n刷新令牌被用于请求新的访问令牌. [了解刷新令牌如何用于浏览器应用](https://authok.cn/docs/tokens/concepts/refresh-token-rotation) 来帮助您决定是否需要使用它们.\n\n要使用刷新令牌, 需设置 `useRefreshTokens` 选项为 `true`:\n\n```js\nawait createAuthokClient({\n  domain: '<AUTHOK_DOMAIN>',\n  client_id: '<AUTHOK_CLIENT_ID>',\n  redirect_uri: '<MY_CALLBACK_URL>',\n  useRefreshTokens: true\n});\n```\n\n此设置会让 SDK 自动发送 `offline_access` scope 到授权服务器. 刷新令牌 会被用于交换新的 访问令牌, 直接调用 `/oauth/token` 端点而非使用隐藏 iframe. 这意味着多数情况下 SDK 在使用 刷新令牌 时 不需要依赖第三方 cookies.\n\n**注意** 此配置选项需要 [为你的 Authok 租户开启](https://docs.authok.cn/tokens/guides/configure-refresh-token-rotation) 轮换刷新令牌.\n\n#### 刷新令牌回退\n\n在刷新令牌不可用的情况下, SDK 会回退到使用传统技术方案, 即使用带有 `prompt=none` 的隐藏 iframe 来尝试获取新的访问令牌和刷新令牌.\n例如，如果您正在使用内存缓存并且刷新了页面，就会出现这种情况。在这种情况下，以前存储的任何刷新令牌都将丢失.\n\n如果回退机制失败，将抛出一个 `login_required` 错误，可以对其进行处理，以便让用户重新进行身份验证.\n\n**注意**: 此回退机制仍然需要访问 Authok 的会话 cookie，因此如果第三方 cookie 被阻止，则回退将不起作用，用户必须重新验证才能获得新的刷新令牌.\n\n### 组织\n\n[组织](https://docs.authok.cn/organizations) 主要便于开发和维护 SaaS 和 B2B 应用.\n\n#### 登录组织\n\n通过指定 client 的 `organization` 选项来登录组织:\n\n```js\ncreateAuthokClient({\n  domain: '<AUTHOK_DOMAIN>',\n  client_id: '<AUTHOK_CLIENT_ID>',\n  redirect_uri: '<MY_CALLBACK_URL>',\n  organization: '<MY_ORG_ID>'\n});\n```\n\n也可以在登录时指定组织:\n\n```js\n// 使用重定向\nclient.loginWithRedirect({\n  organization: '<MY_ORG_ID>'\n});\n\n// 使用弹出窗\nclient.loginWithPopup({\n  organization: '<MY_ORG_ID>'\n});\n```\n\n#### 接受用户邀请\n\n通过 SDK 接受用户邀请, 方法是在应用程序中创建可处理用户邀请 URL 的路由,\n并通过从此 URL 传递“organization”和“invitation”参数来登录用户。您可以根据需要使用 `loginWithRedirect` 或 `loginWithPopup`.\n\n```js\nconst url = new URL(invitationUrl);\nconst params = new URLSearchParams(url.search);\nconst organization = params.get('organization');\nconst invitation = params.get('invitation');\n\nif (organization && invitation) {\n  client.loginWithRedirect({\n    organization,\n    invitation\n  });\n}\n```\n\n### 高级选项\n\n可以在配置 `AuthokClient` 时通过 `advancedOptions` 属性来配置 高级选项. 参考 [API 文档](https://authok.github.io/authok-spa-js/interfaces/advancedoptions.html) 来了解高级选项的完整设置.\n\n```js\ncreateAuthokClient({\n  domain: '<AUTHOK_DOMAIN>',\n  client_id: '<AUTHOK_CLIENT_ID>',\n  advancedOptions: {\n    defaultScope: 'email' // 修改每个 authz 请求的 scopes. **注意**: `openid` 始终都会被指定\n  }\n});\n```\n\n## 贡献\n\n感谢所有对本仓库的返回和贡献! 在开始之前，先参考:\n\n- [Authok 的一般贡献指南](https://github.com/authok/open-source-template/blob/main/GENERAL-CONTRIBUTING.md)\n- [Authok 的行为准则指南](https://github.com/authok/open-source-template/blob/main/CODE-OF-CONDUCT.md)\n- [本仓库的贡献指南](https://github.com/authok/authok-spa-js/blob/main/CONTRIBUTING.md)\n\n## 支持 + 反馈\n\n如需支持或提供反馈, 请 [在我们的问题追踪器上提出问题](https://github.com/authok/authok-spa-js/issues).\n\n## 常见问题\n\n有关使用 SDK 时可能遇到的常见问题，请查看[the FAQ](https://github.com/authok/authok-spa-js/blob/master/FAQ.md).\n\n## 安全风险报告\n\n请不要在公共 GitHub 问题跟踪器上报告安全漏洞. [Responsible Disclosure Program](https://authok.cn/whitehat)  详细说明了披露安全问题的流程.\n\n## Authok 是什么?\n\nAuthok 可以帮助您:\n\n- 使用多个身份提供者进行身份认证, 包括 社会化 (例如, 微信, 企业微信, 支付宝, 抖音, 微博, Google, Facebook, Microsoft, LinkedIn, GitHub, Twitter), 或者 企业 (例如, Windows Azure AD, Google Apps, Active Directory, ADFS, SAML)\n- 通过 用户名/密码 数据库, 免密模式, 多因素认证 等多种模式进行登录\n- 连接多个用户账号\n- 生成签名的 JSON Web 令牌以授权 API 调用并安全地传递用户身份\n- 登录方式、时间和地点等统计和分析\n- 使用可定制的 JavaScript 规则从其他数据源丰富用户档案\n\n[为什么使用 Authok?](https://authok.cn/why-authok)\n\n## 许可\n\n本项目基于 MIT 许可. 参考 [LICENSE](https://github.com/authok/authok-spa-js/blob/master/LICENSE) 以了解更多信息.\n","readmeFilename":"README.md"}