I’m attempting to use live_view in a chrome extension. It worked fine for some time, then stopped in Chrome (presumably due to a security update). It continued to work in Edge for some time, then stopped (presumably because they trail on security updates). Now when I attempt to run my application, I get:
LiveView session was misconfigured or the user token is outdated.
1) Ensure your session configuration in your endpoint is in a module attribute:
@session_options [
...
]
2) Change the `plug Plug.Session` to use said attribute:
plug Plug.Session, @session_options
3) Also pass the `@session_options` to your LiveView socket:
socket "/live", Phoenix.LiveView.Socket,
websocket: [connect_info: [session: @session_options]]
4) Define the CSRF meta tag inside the `<head>` tag in your layout:
<%= csrf_meta_tag() %>
5) Pass it forward in your app.js:
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content");
let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}});
I’ve been able to make this work by bundling up my js in Webpack like this:
"chrome_app": "webpack js/chrome_app.js -o js/bundle.js --mode development --watch"
And get the web app working by making a seperate chrome_app.js, like this:
var xhr = new XMLHttpRequest();
xhr.responseType = 'document';
xhr.open('GET', 'http://localhost:4000/process_administrator', true)
xhr.onload = function(e) {
document.documentElement.replaceChild(this.response.head, document.head)
document.documentElement.replaceChild(this.response.body, document.body)
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
console.log(csrfToken)
let liveSocket = new LiveSocket("ws://localhost:4000/live", Socket, {
params: { _csrf_token: csrfToken},
hooks: Hooks
})
window.addEventListener("phx:page-loading-start", info => NProgress.start())
window.addEventListener("phx:page-loading-stop", info => NProgress.done())
liveSocket.connect()
window.liveSocket = liveSocket
}
xhr.send()
It’s a little cheesy but it’s been working. I’ve validated that it passes in the csrf token in the websocket transaction, but phoenix always returns stale, like:
["4", "4", "lv:phx-Fj-Fa5KtHwBF1jOB", "phx_reply", {response: {reason: "stale"}, status: "error"}]
I’m starting to dig in to the guts of live_view and I’ve found that in LiveView’s mount function that the phx_socket value contains a nil session.
I’m trying to trace that back into the bowels of live view, and I’m wondering if anyone can help me out.
I’ve also started logging the plug, and I found a difference in my headers between the extension and the “normal” browser. Here’s the headers from the browser (working):
req_headers: [
{"accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"},
{"accept-encoding", "gzip, deflate, br"},
{"accept-language", "en-US,en;q=0.9"},
{"cache-control", "max-age=0"},
{"connection", "keep-alive"},
{"cookie",
"_userdocs_web_key=SFMyNTY.g3QAAAACbQAAAAtfY3NyZl90b2tlbm0AAAAYNFZZNzBSLVlCNjdHNmE2SUVlZWVZTFdWbQAAABF1c2VyZG9jc193ZWJfYXV0aG0AAAB2U0ZNeU5UWS5kWE5sY21SdlkzTmZkMlZpWDJNd05qVmlNR1kwTFRjeU16WXROREZtT0MxaE9HVXhMV0UyT0dGbE1USmpPVGMwWXcubUlsZ3pseGVVck5heXBxZ21MZ2p4Vkl0b2RnblRtNy1DWGg0OVBCVlJQOA.-IIyIbAN2-362-wIU4e69Wjw_-jjRxdaqfjx1vUeF6Q"},
{"host", "localhost:4000"},
{"sec-fetch-dest", "document"},
{"sec-fetch-mode", "navigate"},
{"sec-fetch-site", "none"},
{"sec-fetch-user", "?1"},
{"upgrade-insecure-requests", "1"},
{"user-agent",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36"}
],
Here’s the headers from the extension (not working):
req_headers: [
{"accept", "*/*"},
{"accept-encoding", "gzip, deflate, br"},
{"accept-language", "en-US,en;q=0.9"},
{"connection", "keep-alive"},
{"cookie",
"_userdocs_web_key=SFMyNTY.g3QAAAACbQAAAAtfY3NyZl90b2tlbm0AAAAYc3UySngzZXZZM2JrMDg3WFZFRlF6QzdNbQAAABF1c2VyZG9jc193ZWJfYXV0aG0AAAB2U0ZNeU5UWS5kWE5sY21SdlkzTmZkMlZpWDJKaU5XUmlNamxsTFdNNE1tVXRORGcyTXkxaFkySmhMV1l4T1dWaVpEaGxPVGcxTVEuaHNHNWFzSGNuMWxhOGtXeFEyZ0JfTVBHTDRFc3I5OFlHWTdkSVBHcXhXcw.eZk4nKTljgEr2BLm0QRBTR4hhu8Om8vB7N1dRBme4Is"},
{"host", "localhost:4000"},
{"sec-fetch-dest", "empty"},
{"sec-fetch-mode", "cors"},
{"sec-fetch-site", "none"},
{"user-agent",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.80 Safari/537.36 Edg/86.0.622.43"}
],