as title says I'm writing a paid Desktop App that automates some process, it indirectly requires internet connection because MY app automates another Desktop app that requires internet connection. There is no webpage or such, only my Desktop App and my API.
Normal Workflow:
- User opens Desktop App: Login prompt shows on screen (it's a simple interface written in c++ that then posts to my API).
- User presses the "Login" button: Data is sent via POST to my API.
- API validates and verifies the data, then generates a JWT and sends it to the user.
- User then uses the App all the time he/she wants: Every X seconds the JWT is sent to the API to see if it's still valid.
- The user stops using the App: It might be because the App crashed, because he lost connection or because he closed it.
What I want to achieve:
- I need it to be secure for the users and for me (by me I mean I don't want it to be easily pirated):
- I'm using HTTPS.
- I'm hashing the Password before sending it to my API.
- I'm validating and verifying all the data.
- I don't know how to make sure that this data comes from my Desktop App and was not modified in the middle by the user (like replacing an unique identifier with a simple string).
- I want to prevent multiple clients logging in using the same account at the same time:
- I don't want multiple Apps connected at the same time using the same account. I don't mind if an user uses the same account on different computers as long as he is not having more than 1 App connected at the same time.
- When a user logs in with an account it will kill the rest of the "sessions" that this account had. (Like an online game where if you log in with an account that's already logged in, it will kick the user that was logged in preventing from 2 clients using the same account at the same time).
My schema:
Using JWT, when user "A" logs in it will generate a new JWT using his username and some kind of unique information like IP or computer information.
My Desktop App will verify and store this JWT in memory. Then every X seconds it will do a POST request sending the JWT to see if it's still valid.
- If everything is okay then the App will continue to run normally.
- If the token is not valid anymore or something is wrong it will log out.
Problems I found:
Let's say User "A" logs in and a JWT is then generated and sent to the Desktop App, how can the Desktop App tell that this JWT is valid and that is not a fake response the user is using so the App thinks it's logged in?.
What happens if user "A" logs in and then fakes responses every X seconds? I mean, how can I make this response unique? Is it a good fix to generate a new JWT everytime it performs this check?
Let's say I make it unique using some kind of unique identifier for each client (like IP, computer information, etc.), what if the user intercepts the information and replaces it with something simple like "hello world" so then all clients can use the same account and have a valid token at the same time. How do I prevent user from being able to intercept the data sent?
So my questions are:
- How do I fix those problems.
- Is it a good schema? I mean is it secure (to prevent piracy)? (I know nothing is 100% secure, but I don't want to make an authentication system that can be easily broken or with no security at all).
- Is JWT a good choice here? Are there alternatives that are "better" or "different"?
- Do you see any other problems, flaws, bugs, etc.?
- Do you have another schema or idea to achieve this?
Thanks in advance.
P.S.: I'm not taking into account what happens if the user reverses my Desktop App because that's another topic and in that case nothing here is important.