user3370864
user3370864

Reputation: 11

How to send Emails using oauth authentication instead of username and password in objective c

Im working on an iPhone application that must allow to send emails automatically, without any user interaction (I can't use MFMailComposeViewController nor store user's username/password to use them with an SMTP library like SKPSMTP or MailCore). My idea to allow the user, to login with his Gmail account using OAuth protocol, and then, in other moment, use the access_token previously given, for sending emails without need to re authenticate or ask the user for any additional data. I am using the GoogleOpenSource.framework and GooglePlus.framework to login the user. Any suggestion will be helpful. Thanks in advance.

Upvotes: 0

Views: 1178

Answers (2)

user3370864
user3370864

Reputation: 11

Finally, I found the solution to my problem. Next, I detail the steps I made to send emails with google using OAuth Authentication:

For the OAuth login I used GPPSignIn class included on GooglePlus.framework. For those could be interested, just follow the instructions listed here and here. In the login window, after finished the process, the next delegate method will be called:

- (void)finishedWithAuth: (GTMOAuth2Authentication *)auth error: (NSError *) error {
    NSLog(@"Received error %@ and auth object %@",error, auth);
    if(error) {
        NSLog(@"%@",[error description]);
    }
    else {
        // Get the refresh token.
        self.refreshToken = auth.refreshToken;

        // If you need the user's email you must set the permissions on the GPPSignIn instance.
        // store it locally for future uses.
        self.email = [GPPSignIn sharedInstance].userEmail;
    }
}

Then, for sending emails, I used MailCore's library. When you want to send an email with your OAuth accessToken, first you have to fetch the updated token with the refresh token you previously saved in the login process:

- (void)sendMail {

    GTMOAuth2Authentication * auth = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:GOOGLE_OAUTH_KEYCHAIN clientID:GOOGLE_CLIENT_ID clientSecret:GOOGLE_CLIENT_SECRET];

    //I use the saved refreshToken    
    auth.refreshToken = refreshToken;


    [auth beginTokenFetchWithDelegate:self
                didFinishSelector:@selector(auth:finishedRefreshWithFetcher:error:)];

}

- (void)auth:(GTMOAuth2Authentication *)auth finishedRefreshWithFetcher:(GTMHTTPFetcher *)fetcher error:(NSError *)error {

    if (error != nil) {
         NSLog(@"Authentication failed");
         return;
    }

    NSString * email = storedEmail;
    NSString * accessToken = [auth accessToken];


    MCOSMTPSession * smtpSession = [[MCOSMTPSession alloc] init];

    smtpSession = [[MCOSMTPSession alloc] init];
    smtpSession.hostname = @"smtp.gmail.com";
    smtpSession.port = 465;
    smtpSession.username = email; //saved value
    smtpSession.connectionType = MCOConnectionTypeTLS;
    smtpSession.password = nil; //nil
    smtpSession.OAuth2Token = accessToken; //saved value
    smtpSession.authType = MCOAuthTypeXOAuth2;

    MCOMessageBuilder * builder = [[MCOMessageBuilder alloc] init];

    MCOAddress *fromAddress = [MCOAddress addressWithMailbox:email];
    MCOAddress *toAddress = [MCOAddress addressWithMailbox:recipientEmail];

    [[builder header] setFrom:fromAddress];
    [[builder header] setTo:toAddresses];
    [[builder header] setSubject:@"Some subject"];
    [builder setHTMLBody:@"some message"];
    NSData * rfc822Data = [builder data];

    MCOSMTPSendOperation *sendOperation = [smtpSession sendOperationWithData:rfc822Data];
    [sendOperation start:^(NSError *error) {
        if(error) {
            NSLog(@"%@ Error sending email:%@", email, error);
        } else {
            NSLog(@"%@ Successfully sent email!", email);
        }
    }];
}

Upvotes: 1

Nicolas Riousset
Nicolas Riousset

Reputation: 3619

You should be able to authenticate against GMAIL smtp server using your OAUTH token with this SMTP command :

AUTH XOAUTH <your OAUTH token>

Usage of OAUTH with GMail SMTP server is documented by Google here. You'll will find there more documentation from Google, including the following SMTP OAUTH session sample :

[connection begins]
S: 220 mx.google.com ESMTP 12sm2095603fks.9
C: EHLO sender.example.com
S: 250-mx.google.com at your service, [172.31.135.47]
S: 250-SIZE 35651584
S: 250-8BITMIME
S: 250-AUTH LOGIN PLAIN XOAUTH
S: 250-ENHANCEDSTATUSCODES
S: 250 PIPELINING
C: AUTH XOAUTH R0VUIGh0dHBzOi8vbWFpbC5nb29nbGUuY29tL21ha
WwvYi9zb21ldXNlckBleGFtcGxlLmNvbS9zbXRwLyBvYXV0aF9jb25zd
W1lcl9rZXk9ImFub255bW91cyIsb2F1dGhfbm9uY2U9IjIwNDg1MjE2O
DgzNjgyNzY0MzAiLG9hdXRoX3NpZ25hdHVyZT0iVEJNQmo2NG9ZMzNJd
ERUOWxtUGlveGF0Uko0JTNEIixvYXV0aF9zaWduYXR1cmVfbWV0aG9kP
SJITUFDLVNIQTEiLG9hdXRoX3RpbWVzdGFtcD0iMTI2NzIwNTc2OSIsb
2F1dGhfdG9rZW49ImFzZGZhc2RmIixvYXV0aF92ZXJzaW9uPSIxLjAi
S: 235 2.7.0 Accepted
[connection continues...]

I'm not familiar with iPhone development, so I won't be able to provide you with some sample code. But you'll need a SMTP library supporting extended authentication schemes.

Upvotes: 0

Related Questions