I'm considering a scenario where a user installs the app on multiple devices say mobile and desktop; and generates two different tokens.
My current plan is to store both the tokens for the user in database. However, I'm not sure how do I handle the scenario when the token is expired and a new token is generated?
For example, this could be the simple db structure -
id | user_id | token
-------------------------
1 | 1 | asdlgkj090sdf8q (desktop)
2 | 1 | zlkroqiuoiquoio (mobile)
3 | 2 | mnnjnjnjnjojuhq
4 | 2 | 498slkdsflksjfl
If the token for mobile gets updated; I've no way of knowing which row to update.
How do I handle such scenario?
If you want to remove the old token after a new one was generated, I can think of two ways of doing this:
Option 1: Introduce a client id
You could give each client a unique ID that you use to identify it. When you send the new push token to the server, you need to make sure that you also pass the client ID to the server. Your database structure would then look something like that:
id | user_id | client_id | token
------------------------------------------------------
1 | 1 | tthdh | asdlgkj090sdf8q (desktop)
2 | 1 | di4dq | zlkroqiuoiquoio (mobile)
3 | 2 | 5efgd | mnnjnjnjnjojuhq
4 | 2 | 56eff | 498slkdsflksjfl
In your update script (on the server) you will check if a push token exists for the given client id and then either replace the old one or insert a new row.
Option 2: Remember the old token
The second option would be to store the current token on the client, and if it is updated you send both the old and the new token to the server. Then you search for the old token and replace it (or insert a new row if the old token is not present).
If you want to find out if a given token is expired, check this answer. Another approach that I've seen in the Firebase documentation was to remove the token that was used to send a push message if sending the message failed.
The best way to do that is the described method in documentation of server-integration from google:
When a message is sent via an admin SDK, invalid/expired tokens will
throw an error allowing you to then remove them from the database.
So when you send message, response will return from API contain result status with possible values if error can be found in table 9 here:
If response status 200 + and error -> NotRegistered >> that is mean token expires, so delete this token from your database.
Related
I'm having some difficulty with sending a simple GET request via Postman (An application extension in google chrome) to my Laravel 5.2 server. Here are some details to what I'm doing:
Route here:
Next is the code containing the route
Code here (within the laravel routes.php file):
Finally the error that gets thrown
Error Here
I've gone through multiple tutorials (if resources are needed I will post them on request) and videos and yet I think I may have overlooked something. I've even dived into the source code of Laravel's Route handler but it doesn't even get to the method:
$request->send();
located within the public\index.php file on line 56.
When I perform the:
php artisan route:list
I get the following response:
+--------+----------+-----------------------+------+--------------------------------------------------------+-----------------------------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+-----------------------+------+------------------------------------------------------------------------------+-------------+
| | POST | here | | Closure | web |
| | GET|HEAD | user/:id/validate| | \Controllers\UserController#getOAuthValidation | web,api |
+--------+----------+-----------------------+------+--------------------------------------------------------+-----------------------------------+
If ANYONE can shed some light on this I would greatly appreciate it.
strange. Your routes file is /user/validate but your route is expecting an id.
I'm assuming that the validate method requires an id field in its signature?
Remove that, or change your postman get to /user/1/validate
I am trying to scrape a website resultset to create a table with the results from that specific site. On normal login on this site i can use my credentials to access the contents of the site. Site uses HTTPS
However, when i am trying to retrieve the content of this same site through power BI (and more specific Power Query) I am presented with a resultset of two columns and two rows as if the site was asking me for credentials:
|--------------|-------------|
| Username: | |
|--------------|-------------|
| Password: | |
|--------------|-------------|
This is after i entered my credentials when power query asks for them (not returning any error of faulty input). Credentials are correctly entered. When entering bad credentials it gives an error.
I have tried the following options query wise:
Direct input of the desired website
Advanced input with Query and Content optionss in M to force POST() instead of GET().
advanced method 1 - shows login form when executed:
let
Source = Web.Page(
Web.Contents(
"https://url.htm",
[Query=
[mNo ="1234",form name="overviewDetailsForm", id="overviewDetailsForm", method="post"
]
]
)
),
Data0 = Source{0}[Data]
in
Data0
Method 2 - gives an error because option can only be used with anonymous credentials:
let
Source = Web.Page(
Web.Contents(
"https://url.htm",
[Query=
[mNo ="1234",form name="overviewDetailsForm", id="overviewDetailsForm", method="post"
]
],
[Content=Text.ToBinary()
]
)
),
Data0 = Source{0}[Data]
in
Data0
If you use the HTTP debugger Fiddler you should be able to inspect the HTTPS request your browser makes on the site. (You'll have to agree to let Fiddler install a root CA on your machine in order to MITM your internet traffic.) Does your username/password show up in the Auth or Headers tab?
You can typically set any header you want in Web.Contents and they work with Web.Page too, but be aware that some auth tokens will expire over time.
With some trial and error, you should be able to get Power Query to make the same HTTP request as your browser, and you'll get your data!
I can login on my IMAP server using my username, but can't using username#company.com (related: Dovecot Authentication failed if trying login with #domain) . Same thing happens for SMTP with exim4.
How can I setup dovecot (IMAP) and exim4 (SMTP) to allow username#company.com as the login?
EDIT: I'm using driver = passwd for the userdb, and driver = pam for the passdb.
I had the same question, and similar reasons. This may not be the best wa but I used a test account, lets call it 'user' for the sake of illustration and, copied the user's line in /etc/passwd (I'm on a Ubuntu cloud server), and changed the name on the copied line-- just adding the fqdn so the user UID has two names: 'user#mydomain.com' and the original, just 'user'. I setup the account first on Thunderbird with just 'user' to login to dovecot and exim, tested send/recieve ok. Then changed the login on Thunderbird for both servers to 'user#mydomain.com'. I had to re-enter the password, but it appears to have worked spectacularly well. It tested send/recieve ok, and otherwise appears the same as before. Now, I'm short on time so I set the password separately for both accounts, but I'm not sure that part is necessary. I'll have to check later, but I think pam looks up passwords matched to the PID (if I'm wrong about that, please someone tell me!). Anyway, more testing later. I'll let you know if there are deleterious side-effects. Aside: it may be possible to simply add the full email address as an alias in /etc/alias but I haven't tested that, and I just thought of it. Anyone try that one, leave a comment! Thanks! Ciao...
You have to create users in complete form of user#domain.tld.
Setup login autocompletion by #hostname if domain part is omitted, before dovecot-auth invocation.
As far as there is lot of dovecot/exim howtos, there is no ready-to-use recipe for your case.
You can change your SQL query to use only the first part before the # sign by using the substring_index() function. Conveniently, this string search query will return the whole string if there is no # sign. This means that if the customer enters "user#domain.com", it will use the correct value (just the "local_part"), and if the customer enters just "user", it will return the whole string.
Example:
mysql> select substring_index('user#example.net','#',1);
+-------------------------------------------+
| substring_index('user#example.net','#',1) |
+-------------------------------------------+
| user |
+-------------------------------------------+
1 row in set (0.00 sec)
mysql> select substring_index('user','#',1);
+-------------------------------+
| substring_index('user','#',1) |
+-------------------------------+
| user |
+-------------------------------+
1 row in set (0.00 sec)
I'm implementing a basic service to add usernames to user records in a database. The service first checks if the username exists and if it does returns some value to tell the client that the username is already taken. If the username is available it updates the user record and returns "OK". In this application the client is a native IOS mobile app and the server is node.js. But that shouldn't be relevant to this question.
For this service, what would you recommend I use as my return values? For example, when successful should I return a status code 200? A boolean value? A custom string? Similarly for the unsuccessful condition what would the recommended and customary return value be?
The status 201 is intented to be used when some resource is created. So when your user is created you should set status code 201 and set it to 200 when the same request does an update. Additionally you can return the ID id the created/updated user. IMHO you should keep create and update as separate services.
You can use apporpriate 4xx errors (Refer link) when errors happen. Always keep a status message attribute in your response if your response is XML or JSON. You can set appropriate messages into this and the mobile app can check this message based on the HTTP Status Code you give.
I would return a 201 for the successful condition and a 400 or 409 for the unsuccessful condition.
Hope that helps!
Brandon
Following these two links, I was able to implement a simple web service with x509 certification, and an authenticated test client to consume the service.
Right now, it looks something like this:
--------------
| ServiceA.svc | ------------> Test Client 1
| -GetData() |
--------------
How can I extend what I have to accomplish something like this:
--------------
| ServiceA.svc | ------------> Test Client 1
| -GetData() | ------------> Test Client 2
| -SaveData() |
--------------
| ServiceB.svc |-------------> Test Client 1
| -GetData() |
--------------
| ServiceC.svc |-------------> Test Client 2
| -SaveData() |
--------------
I already have services set up, and Test Client 2 ready to go.
So here are some of my questions:
Do I need to create a separate certificate for Test Client 2?
How will the config files/end points/behaviors look like? I think Service B and C would be easy to setup as it is basically the same as what I have right now, but now that ServiceA will be consumed by both clients, I am a bit lost.
If ServiceA is called how do I know which client is calling it? I potentially want to limit the methods they can call (ie. TC1 can only use GetData(), TC2 can only use SaveData()), and be able to log who is accessing the methods.
I can post what I have on the config files if needed, but it looks basically what the two aforementioned links have.
yes, each client needs a separate certificate. Then from within the operation you can get its distinguished identity:
ServiceSecurityContext.Current.PrimaryIdentity.Name
The best practice is to separate the authorization process like described here:
http://msdn.microsoft.com/en-us/magazine/cc948343.aspx