paulanthonywilson / basic_auth Goto Github PK
View Code? Open in Web Editor NEWElixir Plug to easily add HTTP basic authentication to an app
License: MIT License
Elixir Plug to easily add HTTP basic authentication to an app
License: MIT License
If someone tries to omit the colon between username and password, the plug crashes with: ** (MatchError) no match of right hand side value: ["usernamepassword"]
.
This is because the split can't handle it, like highlighted here:
https://github.com/CultivateHQ/basic_auth/blob/master/lib/basic_auth.ex#L92
Hello!
I'd like to avoid using the global mutable state that is Mix.Config for anything other than compile time library configuration. This is easier to test, fits better with Erlang patterns, and is what the core and distillery teams are recommending now :)
It'd be great if this library accepted config like so:
opts = BasicAuth.init(
username: "admin",
password: "simple_password",
realm: "Admin Area"
)
new_conn = BasicAuth.call(conn, opts)
Thanks,
Louis
also, guard with no Phoenix, just with Plug.Router
, by path, possible?
Thank you.
Title says it all really, my basic auth works fine in dev and test, however it won't accept my username/password in production. I enter the details and the box just pops back up again with empty fields. I've tried included the config in prod.exs as well as prod.private.exs (not that it should make a difference) and have tried using environment variables and explicitly defining the credentials. Have also tried submitting blank credentials. (this all makes me think the issue isn't with the credentials themselves).
Environments are (almost) identical, Ubuntu server, sites are behind nginx. Using SSL. There's no setup I can think of that differs between the two, apart from very slightly different domains (.dev and .in).
Is there anything likely to be getting in the way here? Any common things to look for?
Edit: Have just been thinking, I could just set up the basic auth for this site using nginx directly - so if all else fails that's worth a go, but I'd rather resolve the issue if possible.
Hi! I'm new to Elixir. Excuse me if this is not a problem with this library.
I used the callback:
option and the server did not return the WWW-Authenticate
header.
I noticed that it is not sent in one of the functions. Why is that so?
I tried adding it to the conn
myself inside the callback but it didn't make a difference.
I was looking to update cowboy in one of my projects, and it's blocked by basic_auth
. Would you accept a PR for cowboy 2.x support?
I found a fork where someone started this work: https://github.com/NineFX/basic_auth
There is any command to check if the user is logged in or not?
Or some custom code that I can use to achieve this?
Thanks!
Add instructions on how to do this only for certain envs.
I was looking for a library just like this. It looks like it will fit my needs, except that I'd like to use an API key instead of a username and password combination. Any interest in adding that functionality?
Hi,
I'm trying to create an simple plug app (with supervisor flag) to test basic_auth.
However, the result always gets returned even if there is an exception Plug.Conn.AlreadySentError.
curl http://localhost:4000
-> {"data": "hello world}
>iex
[error] Ranch listener UserStoreEx.API.HTTP had connection process started with :cowboy_protocol:start_link/4 at #PID<0.264.0> exit with reason: {{%Plug.Conn.AlreadySentError{message: "the response was already sent"}
Have anybody ever seen it and how can I resolve it?
Thank you very much in advance.
my_app.ex
defmodule MyApp do
use Application
# See http://elixir-lang.org/docs/stable/elixir/Application.html
# for more information on OTP Applications
def start(_type, _args) do
import Supervisor.Spec, warn: false
# Define workers and child supervisors to be supervised
children = [
# Starts a worker by calling: MyApp.Worker.start_link(arg1, arg2, arg3)
# worker(MyApp.Worker, [arg1, arg2, arg3]),
worker(MyRouter, [])
]
# See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
end
my_router.ex
defmodule MyRouter do
import Plug.Conn
use Plug.Router
plug :match
plug :dispatch
plug BasicAuth, realm: "Admin Area", username: "admin", password: "secret"
def start_link do
Plug.Adapters.Cowboy.http(__MODULE__, [])
end
# GET /
get "/" do
{:ok, json} = Poison.encode(%{data: "hello world"})
conn
|> put_resp_content_type("application/json")
|> send_resp(200, json)
end
match _ do
send_resp(conn, 404, "Not Found")
end
end
When using this plug and canceling out of the browser authentication box in Safari, Safari downloads a file rather than display the 401 error message. I believe this is caused by the lack of a response content type being set, and solved by adding Plug.Conn.put_resp_content_type("text/plain")
before Plug.Conn.send_resp(401, "401 Unauthorized")
.
The change is quite simple, but I would be happy to submit a pull request if you would like to consider the change.
Hi @paulanthonywilson ,
First of all, thank you so much for making this library. It has been great help for me.
I wonder if could use this in my Phoenix router definition? I would like to apply basic auth for a certain router scope, so that I don't have to write the plug code in every controller under that scope.
Sort of like this.
defmodule MyApp.Router do
use MyApp, :router
pipeline :admin_auth do
plug(:basic_auth, ...)
end
scope "/admin", as: :admin do
pipe_through([:browser, :admin_auth])
# My router definition
end
Thank you!
Hi. I'm new on Elixir word.
I'm using the BasicAuth on my Router and I want to know if it's possible to define which path will need basic authentication. For example
get("/stats", to: ...)
needs authentication
get("/", to: ...)
do not need authentication
Currently I will need to have a separate controller if I have some actions which need to be secured and others which don't. It would be great if I could use the same controller for both and differentiate them by an except
or only
option.
Possible Example:
plug BasicAuth, use_config: { :your_app, :your_key, except: [:index] }
Both the config file and the router's plug
line are executed at compile time, only storing environment variables when the system is built.
I would like it if basic_auth supported a {:system, "ENV_VAR"}
similar to Phoenix so the values can be configured at run time. See http://hexdocs.pm/phoenix/Phoenix.Endpoint.html:
The
:port
option requires either an integer, string, or{:system, "ENV_VAR"}
. When given a tuple like{:system, "PORT"}
, the port will be referenced fromSystem.get_env("PORT")
at runtime as a workaround for releases where environment specific information is loaded only at compile-time.
This may be due to changes in the framework in the past few months, however the config examples provided aren't getting me very far unfortunately.
Important note: I'm still learning Elixir and Phoenix - so I apologise for any obvious oversights.
This is what I'm getting when running mix test
:
You have configured application :admin_basic_auth in your configuration
file but the application is not available.
This usually means one of:
1. You have not added the application as a dependency in a mix.exs file.
2. You are configuring an application that does not really exist.
Please ensure :admin_basic_auth exists or remove the configuration.
This is using the example provided in the readme:
`config :admin_basic_auth, realm: "Admin", username: "admin", password: "password"``
If I work out what's going wrong before anyone sees this issue, I'll get a pull request in for the readme.
Authentication fails when attempting to use basic_auth
with a password that includes a colon such as password:thathasacolon
.
** (exit) an exception was raised:
** (MatchError) no match of right hand side value: ["username", "password", "thathasacolon"]
lib/basic_auth.ex:88: BasicAuth.respond/3
Is it possible to create a changelog (maybe at least going forward) for this library. I'm currently using version 1.0.0 of this library. Is there a listing of the changes to the current version (2.2.2)?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.