The purpose of this task is to make it impossible to download the Vue-component package (*.js file) knowing the address of the component, but not having an access token.
I'm developing an access control system and a user interface in which the set of available components depends on the user's access level.
The system uses the JSON API and JWT authorization
. For this, Axios is used on the client side. To build the application, we use Webpack 4, to load the components, we use the vue-loader
.
After the user is authorized, the application requests an array of available routes and metadata from the server, then a dynamically constructed menu and routes are added to the VueRouter object.
Below I gave a simplified code.
import axios from 'axios'
import router from 'router'
let API = axios.create({
baseURL: '/api/v1/',
headers: {
Authorization: 'Bearer mySecretToken12345'
}
})
let buildRoutesRecursive = jsonRoutes => {
let routes = []
jsonRoutes.forEach(r => {
let path = r.path.slice(1)
let route = {
path: r.path,
component: () => import(/* webpackChunkName: "restricted/[request]" */ 'views/restricted/' + path)
//example path: 'dashboard/users.vue', 'dashboard/reports.vue', etc...
}
if (r.children)
route.children = buildRoutesRecursive(r.children)
routes.push(route)
})
return routes
}
API.get('user/routes').then(
response => {
/*
response.data =
[{
"path": "/dashboard",
"icon": "fas fa-sliders-h",
"children": [{
"path": "/dashboard/users",
"icon": "fa fa-users",
}, {
"path": "/dashboard/reports",
"icon": "fa fa-indent"
}
]
}
]
*/
let vueRoutes = buildRoutesRecursive(response.data)
router.addRoutes(vueRoutes)
},
error => console.log(error)
)
The problem I'm having is because Webpack loads the components, by adding the 'script' element, and not through the AJAX request. Therefore, I do not know how to add an authorization header to this download. As a result, any user who does not have a token can download the code of the private component by simply inserting his address into the navigation bar of the browser.
Ideally, I would like to know how to import a vue component using Axios.
Or, how to add an authorization header to an HTTP request.
I needed something similar and came up with the following solution. First, we introduce a webpack plugin that gives us access to the script element before it's added to the DOM. Then we can munge the element to use fetch() to get the script source, and you can craft the fetch as needed (e.g. add request headers).
In webpack.config.js:
Now, somewhere convenient in your application js:
Although sspiff's answer looks quite promising, it did not work directly for me.
After some investigation this was mainly due to me using Vue CLI 3 and thus a newer version of webpack. (which is kinda weird as sspiff mentioned using webpack 4.16.1).
Anyway to solve it I used the following source: medium.com, Which gave me the knowledge to edit the given code.
This new code is situated in vue.config.js file:
The second piece of code provided by sspiff has stayed the same and can be placed in the App.vue file or the index.html between script tags.
Also to further improve this answer I will now explain how to split the chunks in Vue CLI 3 for this specific purpose.
as you can see I also added the chainWebpack field to the config. This makes sure that webpack does not add prefetch tags in the index.html. (e.g. it will now only load lazy chunks when they are needed)
To further improve your splitting I suggest changing all your imports to something like:
This will make sure that all your private chunks end up in a private folder and that they will not get prefetched. The public chunks will end up in a public folder and will get prefetched.
For more information use the following source how-to-make-lazy-loading-actually-work-in-vue-cli-3
Hope this helps anyone with this problem!
To perform a simple component download using an access token, you can do the following...
1) Use asynchronous component loading with file extraction. Use
webpackChunkName
option to separate file or directory/file, like:2) Configure server redirection for protected files or direcory. Apache htaccess config for example:
3) write a server-side script that checks the token in the header or cookies and gives either the contents of .js or 403 error.