# Super basic authentication

**URL:** <https://support.prodi.gy/t/super-basic-authentication/233>\
**Category:** Uncategorized\
**Tags:** solved\
**Created:** [January 18, 2018, 4:02pm UTC](https://support.prodi.gy/t/super-basic-authentication/233 "2018-01-18T16:02:14Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![andy](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/andy/32/966_2.png) [@andy](https://support.prodi.gy/u/andy)\
**Post date:** [January 18, 2018, 4:02pm UTC](https://support.prodi.gy/t/super-basic-authentication/233/1 "2018-01-18T16:02:15Z")

</div>

I implemented very rudimentary simple HTTP authentication for Prodigy and wanted to share it with anyone who’s interested. I know this isn’t secure but it’s the best I could do with my minimal web skills. It would be great to have something like Jupyter’s token-based authentication some day.

At line 43 of `app.py`, add this:

```python
authentication = hug.authentication.basic(hug.authentication.verify('annotator1', 'mypassword'))

@hug.static('/', requires = authentication)
def serve_static():
    # NB! This currently serves whole drive! Does nothing to prevent '../'
    return (str(Path( __file__ ).parent / 'static'),)

```

I used example code from the [hug repo](https://github.com/timothycrosley/hug/blob/develop/examples/authentication.py#L12).

---

<div class="post-metadata">

**Author:** ![honnibal](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/honnibal/32/35_2.png) [@honnibal](https://support.prodi.gy/u/honnibal)\
**Post date:** [January 19, 2018, 3:15pm UTC](https://support.prodi.gy/t/super-basic-authentication/233/2 "2018-01-19T15:15:02Z")

</div>

Thanks! Glad to hear this was easy.

---

<div class="post-metadata">

**Author:** ![plusepsilon](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/plusepsilon/32/49_2.png) [@plusepsilon](https://support.prodi.gy/u/plusepsilon)\
**Post date:** [January 23, 2018, 11:23pm UTC](https://support.prodi.gy/t/super-basic-authentication/233/3 "2018-01-23T23:23:54Z")

</div>

Nice! Would be really useful if integrated inside Prodigy.

---

<div class="post-metadata">

**Author:** ![schultzca\_tda](https://avatars.discourse-cdn.com/v4/letter/s/b487fb/32.png) [@schultzca\_tda](https://support.prodi.gy/u/schultzca_tda)\
**Post date:** [October 16, 2018, 7:29pm UTC](https://support.prodi.gy/t/super-basic-authentication/233/4 "2018-10-16T19:29:20Z")

</div>

Sorry I feel like I am missing something. How would you apply this to the specific prodigy web app instance? Or are you suggesting modifying the Prodigy source code?

---

<div class="post-metadata">

**Author:** ![ines](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/ines/32/3_2.png) [@ines](https://support.prodi.gy/u/ines)\
**Post date:** [October 16, 2018, 7:32pm UTC](https://support.prodi.gy/t/super-basic-authentication/233/5 "2018-10-16T19:32:31Z")

</div>

Yes, Prodigy ships with the source for its `app.py`, so you can easily adapt it or see how it works and write a similar wrapper using Hug or a different library.

Since this thread was started, @andy has actually developed a super cool open-source extension for Prodigy that implements a multi-user setup plus various other features. You can find it here:

> **[ahalterman/multiuser\_prodigy](https://github.com/ahalterman/multiuser_prodigy)**
>
> Running Prodigy for a team of annotators. Contribute to ahalterman/multiuser\_prodigy development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![schultzca\_tda](https://avatars.discourse-cdn.com/v4/letter/s/b487fb/32.png) [@schultzca\_tda](https://support.prodi.gy/u/schultzca_tda)\
**Post date:** [October 16, 2018, 7:56pm UTC](https://support.prodi.gy/t/super-basic-authentication/233/6 "2018-10-16T19:56:06Z")

</div>

Aw that makes sense now. Thanks for the quick response! I’m going to give this a try 👍

---

<div class="post-metadata">

**Author:** ![koAlech](https://avatars.discourse-cdn.com/v4/letter/k/7ea924/32.png) [@koAlech](https://support.prodi.gy/u/koAlech)\
**Post date:** [March 19, 2019, 8:26pm UTC](https://support.prodi.gy/t/super-basic-authentication/233/7 "2019-03-19T20:26:03Z")

</div>

I applied @andy’s cool hug authentication but it doesn’t work.  
I get this `Oops, something went wrong :(` error after entering the credentials.  
I noticed on Chrome’s developer tools is that the call to `/project` fails with HTTP 401 with the following error message: `{"errors":{"Invalid Authentication":"Provided api_jwt credentials were invalid"}}`

Have I missed something?  
Thanks

---

<div class="post-metadata">

**Author:** ![justindujardin](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/justindujardin/32/169_2.png) [@justindujardin](https://support.prodi.gy/u/justindujardin)\
**Post date:** [March 20, 2019, 4:12pm UTC](https://support.prodi.gy/t/super-basic-authentication/233/8 "2019-03-20T16:12:24Z")

</div>

@koAlech Hurray for authenticating users, and welcome!

We’ve begun integrating more full-featured authentication for Prodigy Scale, and the snippet you used conflicts with that code.

~~A workaround is to remove the occurrences of the string `, requires=conditional_api_token` from `app.py`.~~

~~This will remove your ability to use the `PRODIGY_JWT_*` environment variables, but if you want to use basic auth, that should be no problem.~~

_edit: there’s a better fix below_

---

<div class="post-metadata">

**Author:** ![koAlech](https://avatars.discourse-cdn.com/v4/letter/k/7ea924/32.png) [@koAlech](https://support.prodi.gy/u/koAlech)\
**Post date:** [March 20, 2019, 8:12pm UTC](https://support.prodi.gy/t/super-basic-authentication/233/9 "2019-03-20T20:12:06Z")

</div>

@justindujardin Thanks for the warm welcome!  
I’m kind of a newbie with prodigy but so far it’s just awesome!

Thanks for the workaround but that just authenticates `/`.  
It makes the APIs accessible by anyone.

I guess my only option right now is going with ngrok …  
Any other ideas?

---

<div class="post-metadata">

**Author:** ![justindujardin](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/justindujardin/32/169_2.png) [@justindujardin](https://support.prodi.gy/u/justindujardin)\
**Post date:** [March 20, 2019, 11:42pm UTC](https://support.prodi.gy/t/super-basic-authentication/233/10 "2019-03-20T23:42:30Z")

</div>

> [@koAlech](#):
>
> Thanks for the workaround but that just authenticates `/` .  
> It makes the APIs accessible by anyone.

Hah, you're right, and I found a fix!

In `app.py` around line 43 there is an if statement that checks for the existence of an "Authorization" header value:

```python
@authenticator
def api_jwt(request, response, verify_user, **kwargs):
    token = request.get_header("Authorization")
    bearer_prefix = "Bearer "
    if token:
    ...

```

Updating it to ensure that Authorization header is for a bearer token (and not basic auth) fixes the conflict without removing JWT support:

```python
@authenticator
def api_jwt(request, response, verify_user, **kwargs):
    token = request.get_header("Authorization")
    bearer_prefix = "Bearer "
    if token and bearer_prefix in token:
    ...

```

---

<div class="post-metadata">

**Author:** ![lariverosc](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/lariverosc/32/413_2.png) [@lariverosc](https://support.prodi.gy/u/lariverosc)\
**Post date:** [March 24, 2019, 1:17am UTC](https://support.prodi.gy/t/super-basic-authentication/233/11 "2019-03-24T01:17:11Z")

</div>

I was having authentication issues using ngrok, I suppose the basic authentication header used by ngrok conflicts with the JWT validation, I apply your suggested change and it works fine, thanks.

---

<div class="post-metadata">

**Author:** ![koAlech](https://avatars.discourse-cdn.com/v4/letter/k/7ea924/32.png) [@koAlech](https://support.prodi.gy/u/koAlech)\
**Post date:** [March 26, 2019, 7:56am UTC](https://support.prodi.gy/t/super-basic-authentication/233/12 "2019-03-26T07:56:50Z")

</div>

I ended up creating a https proxy with basic authentication using nginx. Works great after this change!  
The option of enabling basic authentication using hug is not a valid option for us as it only protects `/` and leaves the API calls publicly accessible.  
Thanks for the help @justindujardin!
