Reputation: 5
I'm using the YouTube Data API V3 to upload videos to my youtube channel. The authorisation code in the provided sample code needs manual intervention in authorisation process. Every time when I restart my server, it opens the browser and ask me for authentication and permissions. For my Windows PC, its fine, but I'm going to deploy this code to a remote Linux machine on which I only have SSH access.
Is there any way to make this process automatic? Like by accessing the API using normal credentials(username and password) or making this process one time (permanent authentication/authorisation).
I did read some threads on this topic which points to use refresh token.
Upvotes: 0
Views: 1115
Reputation: 786
Maybe a little late...
1) Create new project in Google Developers Console.
2) Create oauth 2.0 Cliend id. In application type select - Other.
3) Download json file, rename it to "client_secret.json" and add it to /resources folder (for Gradle project).
4) Create java file and add this code:
public class YoutubeAuth {
private static final String CLIENT_SECRETS= "/client_secret.json";
private static final Collection<String> SCOPES =
Arrays.asList("https://www.googleapis.com/auth/youtube.readonly");
private static FileDataStoreFactory dataStoreFactory;
private static final java.io.File DATA_STORE_DIR =
new java.io.File(System.getProperty("user.home"), ".store/youtube");
private static final String APPLICATION_NAME = "Custom Application Name";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
/**
* Create an authorized Credential object.
*
* @return an authorized Credential object.
* @throws IOException
*/
private static Credential authorize(final NetHttpTransport httpTransport) throws IOException {
// Load client secrets.
InputStream in = YoutubeAuth.class.getResourceAsStream(CLIENT_SECRETS);
GoogleClientSecrets clientSecrets =
GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow.Builder(httpTransport, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(dataStoreFactory)
.build();
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
/**
* Build and return an authorized API client service.
*
* @return an authorized API client service
* @throws GeneralSecurityException, IOException
*/
public static YouTube getService() throws GeneralSecurityException, IOException {
final NetHttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
Credential credential = authorize(httpTransport);
return new YouTube.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.build();
}
}
Pay attention to this lines of code:
private static FileDataStoreFactory dataStoreFactory;
private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"),".store/youtube");
and to this method inside authorize() method:
.setDataStoreFactory(dataStoreFactory)
and to this method inside getService() method:
dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
YouTube youtubeService = LfkYoutubeAuth.getService();
...
// some other code
---
So you can use Youtube Service like this
Upvotes: 0
Reputation: 117146
Normally i would say you should use a service account then you wouldn't need to do the authentication process at all. However the YouTube API doesn't support service account authentication.
I am at a lost to explain why your authentication would need to be refreshed after a reboot. Your code should be saving the credentials file which contains a refresh token the refresh token should continue to work even after a reboot. I will hazard to guess there is an issue with your code.
This is a Java Quickstart example which shows how the credentials are saved. Its for people api and not Youtube let me know if you need any help altering it for YouTube. These credentials will not be deleted when the server is rebooted.
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.people.v1.PeopleService;
import com.google.api.services.people.v1.PeopleScopes;
import com.google.api.services.people.v1.model.ListConnectionsResponse;
import com.google.api.services.people.v1.model.Person;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
public class Quickstart {
/** Application name. */
private static final String APPLICATION_NAME =
"People API Java Quickstart";
/** Directory to store user credentials for this application. */
private static final java.io.File DATA_STORE_DIR = new java.io.File(
System.getProperty("user.home"), ".credentials/people.googleapis.com-java-quickstart");
/** Global instance of the {@link FileDataStoreFactory}. */
private static FileDataStoreFactory DATA_STORE_FACTORY;
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY =
JacksonFactory.getDefaultInstance();
/** Global instance of the HTTP transport. */
private static HttpTransport HTTP_TRANSPORT;
/** Global instance of the scopes required by this quickstart.
*
* If modifying these scopes, delete your previously saved credentials
* at ~/.credentials/people.googleapis.com-java-quickstart
*/
private static final List<String> SCOPES =
Arrays.asList(PeopleScopes.CONTACTS_READONLY);
static {
try {
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
} catch (Throwable t) {
t.printStackTrace();
System.exit(1);
}
}
/**
* Creates an authorized Credential object.
* @return an authorized Credential object.
* @throws IOException
*/
public static Credential authorize() throws IOException {
// Load client secrets.
InputStream in =
Quickstart.class.getResourceAsStream("/client_secret.json");
GoogleClientSecrets clientSecrets =
GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(DATA_STORE_FACTORY)
.setAccessType("offline")
.build();
Credential credential = new AuthorizationCodeInstalledApp(
flow, new LocalServerReceiver()).authorize("user");
System.out.println(
"Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
return credential;
}
/**
* Build and return an authorized People client service.
* @return an authorized People client service
* @throws IOException
*/
public static PeopleService getPeopleService() throws IOException {
Credential credential = authorize();
return new PeopleService.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.build();
}
public static void main(String [] args) throws IOException {
PeopleService service = getPeopleService();
// Request 10 connections.
ListConnectionsResponse response = service.people().connections()
.list("people/me")
.setPageSize(10)
.setPersonFields("names,emailAddresses")
.execute();
// Print display name of connections if available.
List<Person> connections = response.getConnections();
if (connections != null && connections.size() > 0) {
for (Person person : connections) {
List<Name> names = person.getNames();
if (names != null && names.size() > 0) {
System.out.println("Name: " + person.getNames().get(0)
.getDisplayName());
} else {
System.out.println("No names available for connection.");
}
}
} else {
System.out.println("No connections found.");
}
}
}
Answer: As for your server issue and how to make this automatic. The answer is you cant. There is no way to authenticate with out a browser window. You should authenticate on your windows pc copy the credentials file I spoke of over to your server.
Upvotes: 0
Reputation: 2411
How are you storing your credentials? If your server shuts down, will your credentials be also lost with it? You could consider storing it in an external database or if it's a web app you can store it as a cookie.
Refresh tokens are only issued once (during the first initial authentication) so if you've already authorized your account before, you'll need to visit your app permissions and remove it. Then try authorizing again, and save that refresh token. If you properly save the refresh token (using cookies/database/whatever), then you'll be given a new access token upon request. Using this method, you won't have to reauthorize every time
Upvotes: 1